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 <cctype>
25 #include <climits>
26 #include <sys/utsname.h>
27 #include "sys/time.h"
28 #include "securec.h"
29 #include "include/sp_utils.h"
30 #include "include/sp_log.h"
31 #include "include/common.h"
32 #include "cpu_collector.h"
33 #include "collect_result.h"
34 #include "include/FPS.h"
35 #include "include/GPU.h"
36 #include "include/Power.h"
37 #include "include/DDR.h"
38 #include "include/profiler_fps.h"
39
40 using namespace OHOS::HiviewDFX;
41 using namespace OHOS::HiviewDFX::UCollectUtil;
42 using namespace OHOS::HiviewDFX::UCollect;
43
44 namespace OHOS {
45 namespace SmartPerf {
46 const unsigned int INT_MAX_LEN = 10;
47 const unsigned int CHAR_NUM_DIFF = 48;
48 const unsigned int UI_DECIMALISM = 10;
49 const unsigned int UI_INDEX_2 = 2;
50 const int BUFFER_SIZE = 1024;
51 const std::string SMART_PERF_VERSION = "1.0.6";
FileAccess(const std::string & fileName)52 bool SPUtils::FileAccess(const std::string &fileName)
53 {
54 return (access(fileName.c_str(), F_OK) == 0);
55 }
HasNumber(const std::string & str)56 bool SPUtils::HasNumber(const std::string &str)
57 {
58 return std::any_of(str.begin(), str.end(), [](char c) { return std::isdigit(c); });
59 }
Cmp(const std::string & a,const std::string & b)60 bool SPUtils::Cmp(const std::string &a, const std::string &b)
61 {
62 if (HasNumber(a) && HasNumber(b)) {
63 std::string stra = a.substr(0, a.find_first_of("0123456789"));
64 std::string strb = b.substr(0, b.find_first_of("0123456789"));
65 if (stra != strb) {
66 return stra < strb;
67 }
68 int numa = SPUtilesTye::StringToSometype<int>(a.substr(stra.length()));
69 int numb = SPUtilesTye::StringToSometype<int>(b.substr(strb.length()));
70 return numa < numb;
71 }
72 return false;
73 }
74
LoadFile(const std::string & filePath,std::string & content)75 bool SPUtils::LoadFile(const std::string &filePath, std::string &content)
76 {
77 char realPath[PATH_MAX] = {0x00};
78 if ((realpath(filePath.c_str(), realPath) == nullptr)) {
79 std::cout << "" << std::endl;
80 }
81 std::ifstream file(realPath);
82 if (!file.is_open()) {
83 return false;
84 }
85
86 file.seekg(0, std::ios::end);
87 file.tellg();
88
89 content.clear();
90 file.seekg(0, std::ios::beg);
91 copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(content));
92 // remove '' \n\r
93 ReplaceString(content);
94 return true;
95 }
96
LoadCmdWithLinkBreak(const std::string & cmd,bool isClearLinkBreak,std::string & result)97 bool SPUtils::LoadCmdWithLinkBreak(const std::string &cmd, bool isClearLinkBreak, std::string &result)
98 {
99 const std::string cmdExc = cmd;
100 FILE *fd = popen(cmdExc.c_str(), "r");
101 if (fd == nullptr) {
102 return false;
103 }
104 char buf[4096] = {'\0'};
105 size_t ret = fread(buf, 1, sizeof(buf) - 1, fd);
106 if (ret >= 0) {
107 buf[ret] = '\0';
108 result = buf;
109 }
110 if (pclose(fd) == -1) {
111 LOGE("Error: Failed to close file");
112 return false;
113 }
114
115 if (isClearLinkBreak) {
116 // remove '' \n\r
117 ReplaceString(result);
118 }
119
120 return ret >= 0 ? true : false;
121 }
122
LoadCmd(const std::string & cmd,std::string & result)123 bool SPUtils::LoadCmd(const std::string &cmd, std::string &result)
124 {
125 return LoadCmdWithLinkBreak(cmd, true, result);
126 }
127
IncludePathDelimiter(const std::string & path)128 std::string SPUtils::IncludePathDelimiter(const std::string &path)
129 {
130 if (!path.empty() && path.back() != '/') {
131 return path + "/";
132 } else {
133 return path;
134 }
135 }
136
ForDirFiles(const std::string & path,std::vector<std::string> & files)137 void SPUtils::ForDirFiles(const std::string &path, std::vector<std::string> &files)
138 {
139 std::string pathStringWithDelimiter;
140 DIR *dir = opendir(path.c_str());
141 if (dir == nullptr) {
142 return;
143 }
144
145 while (true) {
146 struct dirent *ptr = readdir(dir);
147 if (ptr == nullptr) {
148 break;
149 }
150
151 // current dir OR parent dir
152 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
153 continue;
154 } else if (ptr->d_type == DT_DIR) {
155 pathStringWithDelimiter = IncludePathDelimiter(path) + std::string(ptr->d_name);
156 ForDirFiles(pathStringWithDelimiter, files);
157 } else {
158 files.push_back(IncludePathDelimiter(path) + std::string(ptr->d_name));
159 }
160 }
161 closedir(dir);
162 }
163
IsSubString(const std::string & str,const std::string & sub)164 bool SPUtils::IsSubString(const std::string &str, const std::string &sub)
165 {
166 if (sub.empty() || str.empty()) {
167 return false;
168 }
169
170 return str.find(sub) != std::string::npos;
171 }
172
StrSplit(const std::string & content,const std::string & sp,std::vector<std::string> & out)173 void SPUtils::StrSplit(const std::string &content, const std::string &sp, std::vector<std::string> &out)
174 {
175 size_t index = 0;
176 while (index != std::string::npos) {
177 size_t tEnd = content.find_first_of(sp, index);
178 std::string tmp = content.substr(index, tEnd - index);
179 if (tmp != "" && tmp != " ") {
180 out.push_back(tmp);
181 }
182 if (tEnd == std::string::npos) {
183 break;
184 }
185 index = tEnd + 1;
186 }
187 }
188
ExtractNumber(const std::string & str)189 std::string SPUtils::ExtractNumber(const std::string &str)
190 {
191 int cntInt = 0;
192 const int shift = 10;
193 for (int i = 0; str[i] != '\0'; ++i) {
194 if (str[i] >= '0' && str[i] <= '9') {
195 cntInt *= shift;
196 cntInt += str[i] - '0';
197 }
198 }
199 return std::to_string(cntInt);
200 }
201
ReplaceString(std::string & res)202 void SPUtils::ReplaceString(std::string &res)
203 {
204 std::string flagOne = "\r";
205 std::string flagTwo = "\n";
206 std::string::size_type ret = res.find(flagOne);
207 while (ret != res.npos) {
208 res.replace(ret, 1, "");
209 ret = res.find(flagOne);
210 }
211 ret = res.find(flagTwo);
212 while (ret != res.npos) {
213 res.replace(ret, 1, "");
214 ret = res.find(flagTwo);
215 }
216 }
217
GetCurTime()218 long long SPUtils::GetCurTime()
219 {
220 struct timeval tv;
221 gettimeofday(&tv, nullptr);
222 long long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;
223 return timestamp;
224 }
225
GetTopPkgName()226 std::string SPUtils::GetTopPkgName()
227 {
228 std::string cmd = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_HEAD);
229 std::string curTopPkgStr = "";
230 LoadCmd(cmd, curTopPkgStr);
231 uint64_t left = curTopPkgStr.find_first_of("[");
232 uint64_t right = curTopPkgStr.find_first_of("]");
233 std::string topPkg = curTopPkgStr.substr(left + 1, static_cast<int64_t>(right) - static_cast<int64_t>(left) - 1);
234 return topPkg;
235 }
236
GetRadar()237 std::string SPUtils::GetRadar()
238 {
239 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_APP_START);
240 std::string curRadar = "";
241 LoadCmd(cmd, curRadar);
242 return curRadar;
243 }
GetScreen()244 std::string SPUtils::GetScreen()
245 {
246 std::string cmd = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SCREEN);
247 std::string screenStr = "";
248 LoadCmd(cmd, screenStr);
249 uint64_t left = screenStr.find("activeMode");
250 uint64_t right = screenStr.find("capability");
251 std::string screen = screenStr.substr(left, right - left);
252 return screen;
253 }
GetRadarFrame()254 std::string SPUtils::GetRadarFrame()
255 {
256 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_JANK);
257 std::string curRadar = "";
258 LoadCmd(cmd, curRadar);
259 return curRadar;
260 }
GetRadarResponse()261 std::string SPUtils::GetRadarResponse()
262 {
263 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_RESPONSE);
264 std::string curRadar = "";
265 LoadCmd(cmd, curRadar);
266 return curRadar;
267 }
GetRadarComplete()268 std::string SPUtils::GetRadarComplete()
269 {
270 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_COMPLETED);
271 std::string curRadar = "";
272 LoadCmd(cmd, curRadar);
273 return curRadar;
274 }
GetSplitOne(std::string cmd)275 static std::string GetSplitOne(std::string cmd)
276 {
277 std::string result;
278 SPUtils::LoadCmd(cmd, result);
279 return result;
280 }
281
GetDeviceInfoMap()282 std::string SPUtils::GetDeviceInfoMap()
283 {
284 size_t len = 2;
285 bool isTcpMessage = false;
286 std::map<std::string, std::string> deviceInfoMap;
287 std::map<std::string, std::string> cpuInfo = GetCpuInfo(isTcpMessage);
288 std::map<std::string, std::string> gpuInfo = GetGpuInfo(isTcpMessage);
289 std::map<std::string, std::string> deviceInfo = GetDeviceInfo();
290 std::string screenInfos = GetScreen();
291 size_t pos = screenInfos.find(": ");
292 size_t pos1 = screenInfos.find(",");
293 std::string screenSize = screenInfos.substr(pos + len, pos1 - pos - len);
294 deviceInfoMap.insert(cpuInfo.begin(), cpuInfo.end());
295 deviceInfoMap.insert(gpuInfo.begin(), gpuInfo.end());
296 deviceInfoMap.insert(deviceInfo.begin(), deviceInfo.end());
297 deviceInfoMap["activeMode"] = screenSize;
298 if (deviceInfoMap.empty()) {
299 LOGE("Failed to obtain device information");
300 }
301 for (auto iter = deviceInfoMap.cbegin(); iter != deviceInfoMap.cend(); ++iter) {
302 printf("%s: %s\n", iter->first.c_str(), iter->second.c_str());
303 }
304 std::cout << "" << std::endl;
305 return std::string("command exec finished!");
306 }
307
GetDeviceInfo()308 std::map<std::string, std::string> SPUtils::GetDeviceInfo()
309 {
310 std::map<std::string, std::string> resultMap;
311 std::string sn = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::SN));
312 std::string deviceTypeName = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::DEVICET_NAME));
313 std::string brand = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::BRAND));
314 std::string version = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::VERSION));
315 std::string abilist = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::ABILIST));
316 std::string name = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::NAME));
317 std::string model = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::MODEL));
318 std::string fullname = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::FULL_NAME));
319 resultMap["sn"] = sn;
320 resultMap["deviceTypeName"] = deviceTypeName;
321 resultMap["brand"] = brand;
322 resultMap["board"] = "hw";
323 resultMap["version"] = version;
324 resultMap["abilist"] = abilist;
325 resultMap["name"] = name;
326 resultMap["model"] = model;
327 resultMap["fullname"] = fullname;
328 resultMap["daemonPerfVersion"] = SMART_PERF_VERSION;
329 return resultMap;
330 }
GetCpuInfo(bool isTcpMessage)331 std::map<std::string, std::string> SPUtils::GetCpuInfo(bool isTcpMessage)
332 {
333 std::string clusterNames;
334 std::vector<std::string> policyFiles;
335 std::map<std::string, std::string> resultMap;
336 std::string basePath = "/sys/devices/system/cpu/cpufreq/";
337 DIR *dir = opendir(basePath.c_str());
338 if (dir == nullptr) {
339 return resultMap;
340 }
341 while (true) {
342 struct dirent *ptr = readdir(dir);
343 if (ptr == nullptr) {
344 break;
345 }
346 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
347 continue;
348 }
349 std::string clusterName = std::string(ptr->d_name);
350 if (!isTcpMessage) {
351 clusterNames += clusterName + " ";
352 resultMap["cpu_cluster_name"] = clusterNames;
353 }
354 policyFiles.push_back(IncludePathDelimiter(basePath) + clusterName);
355 }
356 closedir(dir);
357 for (size_t i = 0; i < policyFiles.size(); i++) {
358 std::string cpus;
359 LoadFile(policyFiles[i] + "/affected_cpus", cpus);
360 std::string max;
361 LoadFile(policyFiles[i] + "/cpuinfo_max_freq", max);
362 std::string min;
363 LoadFile(policyFiles[i] + "/cpuinfo_min_freq", min);
364 std::string nameBase;
365 if (!isTcpMessage) {
366 nameBase = "cpu_c" + std::to_string(i + 1) + "_";
367 } else {
368 nameBase = "cpu-c" + std::to_string(i + 1) + "-";
369 }
370 resultMap[nameBase + "cluster"] = cpus;
371 resultMap[nameBase + "max"] = max;
372 resultMap[nameBase + "min"] = min;
373 }
374 return resultMap;
375 }
GetGpuInfo(bool isTcpMessage)376 std::map<std::string, std::string> SPUtils::GetGpuInfo(bool isTcpMessage)
377 {
378 const std::vector<std::string> gpuCurFreqPaths = {
379 "/sys/class/devfreq/fde60000.gpu/",
380 "/sys/class/devfreq/gpufreq/",
381 };
382 std::map<std::string, std::string> resultMap;
383 for (auto path : gpuCurFreqPaths) {
384 if (FileAccess(path)) {
385 std::string max;
386 SPUtils::LoadFile(path + "/max_freq", max);
387 std::string min;
388 SPUtils::LoadFile(path + "/min_freq", min);
389 resultMap["gpu_max_freq"] = max;
390 resultMap["gpu_min_freq"] = min;
391 }
392 }
393 return resultMap;
394 }
395
RemoveSpace(std::string & str)396 void SPUtils::RemoveSpace(std::string &str)
397 {
398 int len = 0;
399
400 for (size_t i = 0; i < str.length(); i++) {
401 if (str[i] != ' ') {
402 break;
403 }
404
405 ++len;
406 }
407
408 if (len > 0) {
409 str = str.substr(len);
410 }
411
412 len = 0;
413 for (size_t i = str.length(); i > 0; --i) {
414 if (str[i - 1] != ' ') {
415 break;
416 }
417
418 ++len;
419 }
420
421 if (len > 0) {
422 for (int i = 0; i < len; i++) {
423 str.pop_back();
424 }
425 }
426 }
427
428
IntegerVerification(std::string str,std::string errorInfo)429 bool SPUtils::IntegerVerification(std::string str, std::string errorInfo)
430 {
431 uint64_t dest = 0;
432 bool isValid = false;
433
434 if (str.empty()) {
435 errorInfo = "option requires an argument";
436 LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
437 return false;
438 }
439 if (str.length() > INT_MAX_LEN) {
440 errorInfo = "invalid option parameters";
441 LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
442 return false;
443 }
444
445 for (size_t i = 0; i < str.length(); i++) {
446 if (str[i] < '0' || str[i] > '9') {
447 errorInfo = "invalid option parameters";
448 LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
449 return false;
450 }
451
452 if (!isValid && (str[i] == '0')) {
453 continue;
454 }
455
456 isValid = true;
457 dest *= UI_DECIMALISM;
458 dest += (str[i] - CHAR_NUM_DIFF);
459 }
460
461 if (dest == 0 || dest > INT_MAX) {
462 errorInfo = "option parameter out of range";
463 LOGE("sour(%s) dest(%u) error(%s)", str.c_str(), dest, errorInfo.c_str());
464 return false;
465 }
466
467 return true;
468 }
469
VeriyParameter(std::set<std::string> & keys,std::string param,std::string & errorInfo)470 bool SPUtils::VeriyParameter(std::set<std::string> &keys, std::string param, std::string &errorInfo)
471 {
472 std::string keyParam;
473 std::string valueParm;
474 std::vector<std::string> out;
475 std::vector<std::string> subOut;
476 std::map<std::string, std::string> mapInfo;
477
478 if (param.empty()) {
479 errorInfo = "The parameter cannot be empty";
480 return false;
481 }
482
483 SPUtils::StrSplit(param, "-", out);
484
485 for (auto it = out.begin(); it != out.end(); ++it) { // Parsing keys and values
486 subOut.clear();
487 SPUtils::StrSplit(*it, " ", subOut);
488 if (mapInfo.end() != mapInfo.find(subOut[0])) {
489 errorInfo = "duplicate parameters -- '" + subOut[0] + "'";
490 return false;
491 }
492
493 if (subOut.size() >= UI_INDEX_2) {
494 keyParam = subOut[0];
495 valueParm = subOut[1];
496 SPUtils::RemoveSpace(keyParam);
497 SPUtils::RemoveSpace(valueParm);
498 mapInfo[keyParam] = valueParm;
499 } else if (subOut.size() >= 1) {
500 keyParam = subOut[0];
501 SPUtils::RemoveSpace(keyParam);
502 mapInfo[keyParam] = "";
503 }
504 }
505
506 if (!VeriyKey(keys, mapInfo, errorInfo)) {
507 LOGE("%s", errorInfo.c_str());
508 return false;
509 }
510
511 if (!VerifyValueStr(mapInfo, errorInfo)) {
512 LOGE("%s", errorInfo.c_str());
513 return false;
514 }
515
516 if (!IntegerValueVerification(keys, mapInfo, errorInfo)) {
517 LOGE("%s", errorInfo.c_str());
518 return false;
519 }
520 return true;
521 }
522
VeriyKey(std::set<std::string> & keys,std::map<std::string,std::string> & mapInfo,std::string & errorInfo)523 bool SPUtils::VeriyKey(std::set<std::string> &keys, std::map<std::string, std::string> &mapInfo,
524 std::string &errorInfo)
525 {
526 for (auto it = mapInfo.begin(); it != mapInfo.end(); ++it) {
527 if (keys.end() == keys.find(it->first)) {
528 errorInfo = "invalid parameter -- '" + it->first + "'";
529 return false;
530 }
531 }
532
533 return true;
534 }
535
VerifyValueStr(std::map<std::string,std::string> & mapInfo,std::string & errorInfo)536 bool SPUtils::VerifyValueStr(std::map<std::string, std::string> &mapInfo, std::string &errorInfo)
537 {
538 auto a = mapInfo.find("VIEW");
539 if (mapInfo.end() != a && a->second.empty()) { // Cannot be null
540 errorInfo += "option requires an argument -- '" + a->first + "'";
541 return false;
542 }
543 a = mapInfo.find("PKG");
544 if (mapInfo.end() != a && a->second.empty()) { // Cannot be null
545 errorInfo += "option requires an argument -- '" + a->first + "'";
546 return false;
547 }
548 a = mapInfo.find("OUT");
549 if (mapInfo.end() != a) {
550 if (a->second.empty()) {
551 errorInfo += "option requires an argument -- '" + a->first + "'";
552 return false;
553 }
554 // The total length of file path and name cannot exceed PATH_MAX
555 if (a->second.length() >= PATH_MAX) {
556 errorInfo +=
557 "invalid parameter, file path cannot exceed " + std::to_string(PATH_MAX) + " -- '" + a->first + "'";
558 return false;
559 }
560 size_t pos = a->second.rfind('/');
561 if (pos == a->second.length()) { // not file name
562 errorInfo += "invalid parameter,not file name -- '" + a->first + "'";
563 return false;
564 }
565 if (std::string::npos != pos &&
566 (!SPUtils::FileAccess(a->second.substr(0, pos)))) { // determine if the directory exists
567 errorInfo += "invalid parameter,file path not found -- '" + a->first + "'";
568 return false;
569 }
570 std::string outStr = a->second;
571 std::vector<std::string> outList;
572 SPUtils::StrSplit(outStr, "/", outList);
573 for (auto it = outList.begin(); outList.end() != it; ++it) {
574 if ((*it).length() >= NAME_MAX) {
575 errorInfo += "invalid parameter, file directory or name cannot exceed 255 -- '" + a->first + "'";
576 return false;
577 }
578 }
579 }
580 return true;
581 }
582
IntegerValueVerification(std::set<std::string> & keys,std::map<std::string,std::string> & mapInfo,std::string & errorInfo)583 bool SPUtils::IntegerValueVerification(std::set<std::string> &keys, std::map<std::string, std::string> &mapInfo,
584 std::string &errorInfo)
585 {
586 std::vector<std::string> integerCheck; // Number of integers to be detected
587
588 if (keys.end() != keys.find("N")) {
589 integerCheck.push_back("N");
590 }
591 if (keys.end() != keys.find("fl")) {
592 integerCheck.push_back("fl");
593 }
594 if (keys.end() != keys.find("ftl")) {
595 integerCheck.push_back("ftl");
596 }
597
598 for (auto it = integerCheck.begin(); it != integerCheck.end(); ++it) {
599 auto a = mapInfo.find(*it);
600 if (mapInfo.end() != a) {
601 if (a->second.empty()) {
602 errorInfo += "option requires an argument -- '" + a->first + "'";
603 return false;
604 }
605 if (!SPUtils::IntegerVerification(a->second, errorInfo)) {
606 errorInfo += "option parameter out of range -- '" + a->first + "'";
607 return false;
608 }
609 }
610 }
611
612 return true;
613 }
614
IsHmKernel()615 bool SPUtils::IsHmKernel()
616 {
617 bool isHM = false;
618 utsname unameBuf;
619 if ((uname(&unameBuf)) == 0) {
620 std::string osRelease = unameBuf.release;
621 isHM = osRelease.find("HongMeng") != std::string::npos;
622 }
623 return isHM;
624 }
625
GetCpuNum()626 std::string SPUtils::GetCpuNum()
627 {
628 std::string cpuCores = "cpuCores||";
629 std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
630 CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
631 std::vector<CpuFreq> &cpufreq = result.data;
632 size_t cpuNum = cpufreq.size();
633 cpuCores += std::to_string(cpuNum);
634 if (cpuNum == 0) {
635 std::cout << "CPU frequency collection failed." << std::endl;
636 LOGE("CPU frequency collection failed.");
637 }
638 return cpuCores;
639 }
GetCurrentTime(int prevTime)640 void SPUtils::GetCurrentTime(int prevTime)
641 {
642 LOGD("SPUtils::prevTime (%d)", prevTime);
643 unsigned long sleepNowTime = 10000;
644 bool shouldContinue = true;
645 while (shouldContinue) {
646 struct timespec time1 = { 0 };
647 clock_gettime(CLOCK_MONOTONIC, &time1);
648 int curTimeNow = static_cast<int>(time1.tv_sec - 1);
649 if (curTimeNow == prevTime) {
650 usleep(sleepNowTime);
651 } else {
652 shouldContinue = false;
653 }
654 }
655 }
656
IsForeGround(const std::string & pkg)657 bool SPUtils::IsForeGround(const std::string &pkg)
658 {
659 bool isFoundAppName = false;
660 bool isForeground = false;
661 std::string result;
662 const std::string cmd = "hidumper -s AbilityManagerService -a -l";
663 if (cmd.empty()) {
664 LOGI("cmd is null");
665 return false;
666 }
667
668 FILE *fd = popen(cmd.c_str(), "r");
669 if (fd == nullptr) {
670 return false;
671 }
672 size_t bytesRead;
673 std::array<char, BUFFER_SIZE> buf;
674 while ((bytesRead = fread(buf.data(), 1, buf.size(), fd) > 0)) {
675 result.append(buf.data(), bytesRead);
676 }
677 if (pclose(fd) == -1) {
678 LOGE("Error: failed to close file");
679 return false;
680 }
681
682 std::istringstream iss(result);
683 std::string line;
684 while (std::getline(iss, line)) {
685 if (!isFoundAppName && line.find("mission name #[#" + pkg) != std::string::npos) {
686 isFoundAppName = true;
687 }
688 if (isFoundAppName) {
689 if (line.find("state") != std::string::npos) {
690 isForeground = IsFindForeGround(line);
691 break;
692 }
693 }
694 }
695 return isForeground;
696 }
697
IsFindForeGround(const std::string & line)698 bool SPUtils::IsFindForeGround(const std::string &line)
699 {
700 return line.find("FOREGROUND") != std::string::npos;
701 }
702
IsFindAbilist()703 bool SPUtils::IsFindAbilist()
704 {
705 std::string abilist = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::ABILIST));
706 std::string brand = GetSplitOne(DEVICE_CMD_MAP.at(DeviceCmd::BRAND));
707 if (abilist.find("arm") != std::string::npos && brand.find("HUA") != std::string::npos) {
708 return true;
709 } else if (abilist.find("arm") != std::string::npos && brand.find("HUA") == std::string::npos) {
710 return OHOS::SmartPerf::FPS::GetInstance().SetOtherDeviceFlag();
711 } else {
712 return false;
713 }
714 }
SetRkFlag()715 void SPUtils::SetRkFlag()
716 {
717 bool findAbilistResult = IsFindAbilist();
718 if (!findAbilistResult) {
719 OHOS::SmartPerf::FPS::GetInstance().SetRkFlag();
720 OHOS::SmartPerf::Power::GetInstance().SetRkFlag();
721 OHOS::SmartPerf::GPU::GetInstance().SetRkFlag();
722 OHOS::SmartPerf::ProfilerFPS::GetInstance().SetRkFlag();
723 OHOS::SmartPerf::DDR::GetInstance().SetRkFlag();
724 }
725 }
GetPathPermissions(const std::string & path)726 bool SPUtils::GetPathPermissions(const std::string &path)
727 {
728 const std::string dataCsv = "/data/local/tmp/data.csv";
729 const std::string indexInfoCsv = "/data/local/tmp/smartperf/1/t_index_info.csv";
730 int isDataCsv = strcmp(path.c_str(), dataCsv.c_str());
731 int isIndexInfoCsv = strcmp(path.c_str(), indexInfoCsv.c_str());
732 if (!path.empty()) {
733 std::string cmdResult;
734 std::string cmd;
735 if (isDataCsv == 0 || isIndexInfoCsv == 0) {
736 cmd = "ls -l " + path;
737 LoadCmd(cmd, cmdResult);
738 std::string result = cmdResult.substr(0, 10);
739 return result == "-rw-r--r--";
740 } else {
741 LOGE("the path is false");
742 return false;
743 }
744 } else {
745 LOGE("THE path is empty");
746 return false;
747 }
748 }
749
GetIsGameApp(std::string pkg)750 bool SPUtils::GetIsGameApp(std::string pkg)
751 {
752 bool isGame = false;
753 const std::string cmd = "hidumper -s 66006 -a '-t " + pkg + "'";
754 LOGD("SPUtils::GetIsGameApp cmd (%s)", cmd.c_str());
755 FILE *fd = popen(cmd.c_str(), "r");
756 if (fd == nullptr) {
757 LOGD("ProfilerFPS::fd is empty");
758 return false;
759 }
760 char buf[1024] = {'\0'};
761 while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
762 std::string line(buf);
763 if (line.find("---") != std::string::npos || line.length() <= 1) {
764 continue;
765 }
766 if (line.find("bundleName unknown") != std::string::npos) {
767 isGame = false;
768 break;
769 } else {
770 std::vector<std::string> params;
771 SPUtils::StrSplit(line, " ", params);
772 if (params[0] == "1" && params[1] == pkg) {
773 isGame = true;
774 LOGD("SPUtils::GetIsGameApp isGame", isGame);
775 break;
776 }
777 }
778 }
779 if (pclose(fd) == -1) {
780 LOGE("SPUtils::IsGameApp Error Failed to close file");
781 }
782 return isGame;
783 }
GetVersion()784 std::string SPUtils::GetVersion()
785 {
786 return SMART_PERF_VERSION;
787 }
788 }
789 }
790