• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <future>
17 #include <thread>
18 #include <fstream>
19 #include <sstream>
20 #include <algorithm>
21 #include <unistd.h>
22 #include <dirent.h>
23 #include <cstdio>
24 #include <cstdlib>
25 #include <climits>
26 #include <cctype>
27 #include <climits>
28 #include <dlfcn.h>
29 #include <sys/utsname.h>
30 #include <sys/stat.h>
31 #include "sys/time.h"
32 #include "securec.h"
33 #include "include/sp_utils.h"
34 #include "include/sp_log.h"
35 #include "include/common.h"
36 #include "cpu_collector.h"
37 #include "collect_result.h"
38 #include "include/FPS.h"
39 #include "include/GPU.h"
40 #include "include/Power.h"
41 #include "include/DDR.h"
42 #include "include/FileDescriptor.h"
43 #include "include/Threads.h"
44 #include "parameters.h"
45 
46 #ifdef ARKTEST_ENABLE
47 #include "test_server_client.h"
48 #endif
49 
50 using namespace OHOS::HiviewDFX;
51 using namespace OHOS::HiviewDFX::UCollectUtil;
52 using namespace OHOS::HiviewDFX::UCollect;
53 
54 namespace OHOS {
55 namespace SmartPerf {
56 const unsigned int INT_MAX_LEN = 10;
57 const unsigned int CHAR_NUM_DIFF = 48;
58 const unsigned int UI_DECIMALISM = 10;
59 const unsigned int UI_INDEX_2 = 2;
60 const int BUFFER_SIZE = 1024;
61 const std::string SMART_PERF_VERSION = "1.0.9";
62 const std::string LOWERCASE_H(1, static_cast<char>(104));
63 const std::string LOWERCASE_W(1, static_cast<char>(119));
64 const std::string PRODUCT_NAME = LOWERCASE_H + LOWERCASE_W;
FileAccess(const std::string & fileName)65 bool SPUtils::FileAccess(const std::string &fileName)
66 {
67     return (access(fileName.c_str(), F_OK) == 0);
68 }
69 
HasNumber(const std::string & str)70 bool SPUtils::HasNumber(const std::string &str)
71 {
72     return std::any_of(str.begin(), str.end(), [](char c) { return std::isdigit(c); });
73 }
74 
Cmp(const std::string & a,const std::string & b)75 bool SPUtils::Cmp(const std::string &a, const std::string &b)
76 {
77     if (HasNumber(a) && HasNumber(b)) {
78         std::string stra = a.substr(0, a.find_first_of("0123456789"));
79         std::string strb = b.substr(0, b.find_first_of("0123456789"));
80         if (stra != strb) {
81             return stra < strb;
82         }
83         int numa = SPUtilesTye::StringToSometype<int>(a.substr(stra.length()));
84         int numb = SPUtilesTye::StringToSometype<int>(b.substr(strb.length()));
85         return numa < numb;
86     }
87     return false;
88 }
89 
LoadFile(const std::string & filePath,std::string & content)90 bool SPUtils::LoadFile(const std::string &filePath, std::string &content)
91 {
92     char realPath[PATH_MAX] = {0x00};
93     if ((realpath(filePath.c_str(), realPath) == nullptr)) {
94         std::cout << "" << std::endl;
95     }
96     std::ifstream file(realPath);
97     if (!file.is_open()) {
98         return false;
99     }
100 
101     file.seekg(0, std::ios::end);
102     file.tellg();
103 
104     content.clear();
105     file.seekg(0, std::ios::beg);
106     copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(content));
107     // remove '' \n\r
108     ReplaceString(content);
109     return true;
110 }
111 
LoadCmdWithLinkBreak(const std::string & cmd,bool isClearLinkBreak,std::string & result)112 bool SPUtils::LoadCmdWithLinkBreak(const std::string &cmd, bool isClearLinkBreak, std::string &result)
113 {
114     const std::string cmdExc = cmd;
115     FILE *fd = popen(cmdExc.c_str(), "r");
116     if (fd == nullptr) {
117         return false;
118     }
119     char buf[4096] = {'\0'};
120     size_t ret = fread(buf, 1, sizeof(buf) - 1, fd);
121     if (ret >= 0) {
122         buf[ret] = '\0';
123         result = buf;
124     }
125     if (pclose(fd) == -1) {
126         LOGE("Error: Failed to close file");
127         return false;
128     }
129 
130     if (isClearLinkBreak) {
131         // remove '' \n\r
132         ReplaceString(result);
133     }
134 
135     return ret >= 0 ? true : false;
136 }
137 
LoadCmd(const std::string & cmd,std::string & result)138 bool SPUtils::LoadCmd(const std::string &cmd, std::string &result)
139 {
140     return LoadCmdWithLinkBreak(cmd, true, result);
141 }
142 
IncludePathDelimiter(const std::string & path)143 std::string SPUtils::IncludePathDelimiter(const std::string &path)
144 {
145     if (!path.empty() && path.back() != '/') {
146         return path + "/";
147     } else {
148         return path;
149     }
150 }
151 
ForDirFiles(const std::string & path,std::vector<std::string> & files)152 void SPUtils::ForDirFiles(const std::string &path, std::vector<std::string> &files)
153 {
154     std::string pathStringWithDelimiter;
155     DIR *dir = opendir(path.c_str());
156     if (dir == nullptr) {
157         return;
158     }
159 
160     while (true) {
161         struct dirent *ptr = readdir(dir);
162         if (ptr == nullptr) {
163             break;
164         }
165 
166         // current dir OR parent dir
167         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
168             continue;
169         } else if (ptr->d_type == DT_DIR) {
170             pathStringWithDelimiter = IncludePathDelimiter(path) + std::string(ptr->d_name);
171             ForDirFiles(pathStringWithDelimiter, files);
172         } else {
173             files.push_back(IncludePathDelimiter(path) + std::string(ptr->d_name));
174         }
175     }
176     closedir(dir);
177 }
178 
IsSubString(const std::string & str,const std::string & sub)179 bool SPUtils::IsSubString(const std::string &str, const std::string &sub)
180 {
181     if (sub.empty() || str.empty()) {
182         return false;
183     }
184     return str.find(sub) != std::string::npos;
185 }
186 
StrSplit(const std::string & content,const std::string & sp,std::vector<std::string> & out)187 void SPUtils::StrSplit(const std::string &content, const std::string &sp, std::vector<std::string> &out)
188 {
189     size_t index = 0;
190     while (index != std::string::npos) {
191         size_t tEnd = content.find_first_of(sp, index);
192         std::string tmp = content.substr(index, tEnd - index);
193         if (tmp != "" && tmp != " ") {
194             out.push_back(tmp);
195         }
196         if (tEnd == std::string::npos) {
197             break;
198         }
199         index = tEnd + 1;
200     }
201 }
202 
ExtractNumber(const std::string & str)203 std::string SPUtils::ExtractNumber(const std::string &str)
204 {
205     int cntInt = 0;
206     const int shift = 10;
207     for (int i = 0; str[i] != '\0'; ++i) {
208         if (str[i] >= '0' && str[i] <= '9') {
209             cntInt *= shift;
210             cntInt += str[i] - '0';
211         }
212     }
213     return std::to_string(cntInt);
214 }
215 
ReplaceString(std::string & res)216 void SPUtils::ReplaceString(std::string &res)
217 {
218     std::string flagOne = "\r";
219     std::string flagTwo = "\n";
220     std::string::size_type ret = res.find(flagOne);
221     while (ret != res.npos) {
222         res.replace(ret, 1, "");
223         ret = res.find(flagOne);
224     }
225     ret = res.find(flagTwo);
226     while (ret != res.npos) {
227         res.replace(ret, 1, "");
228         ret = res.find(flagTwo);
229     }
230 }
231 
GetCurTime()232 long long SPUtils::GetCurTime()
233 {
234     struct timeval tv;
235     gettimeofday(&tv, nullptr);
236     long long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;
237     return timestamp;
238 }
239 
GetTopPkgName()240 std::string SPUtils::GetTopPkgName()
241 {
242     std::string cmd = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_HEAD);
243     std::string curTopPkgStr = "";
244     LoadCmd(cmd, curTopPkgStr);
245     uint64_t left = curTopPkgStr.find_first_of("[");
246     uint64_t right = curTopPkgStr.find_first_of("]");
247     std::string topPkg = curTopPkgStr.substr(left + 1, static_cast<int64_t>(right) - static_cast<int64_t>(left) - 1);
248     return topPkg;
249 }
250 
GetRadar()251 std::string SPUtils::GetRadar()
252 {
253     std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_APP_START);
254     std::string curRadar = "";
255     LoadCmd(cmd, curRadar);
256     return curRadar;
257 }
GetScreen()258 std::string SPUtils::GetScreen()
259 {
260     std::string cmd = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SCREEN);
261     std::string screenStr = "";
262     FILE *fd = popen(cmd.c_str(), "r");
263     if (fd == nullptr) {
264         return screenStr;
265     }
266     char buf[4096] = {'\0'};
267     while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
268         std::string line(buf);
269         if (line.find("activeMode") != std::string::npos) {
270             screenStr = line;
271         }
272     }
273     pclose(fd);
274     return screenStr;
275 }
276 
ExecuteCommand(const std::string & command)277 std::string SPUtils::ExecuteCommand(const std::string& command)
278 {
279     std::string result;
280     FILE* pipe = popen(command.c_str(), "r");
281     if (!pipe) {
282         LOGE("popen failed!");
283         return " ";
284     }
285     char buffer[BUFFER_SIZE];
286     size_t bytesRead;
287     while ((bytesRead = fread(buffer, 1, sizeof(buffer), pipe)) > 0) {
288         result.append(buffer, bytesRead);
289     }
290     pclose(pipe);
291     return result;
292 }
GetRadarFrame()293 std::string SPUtils::GetRadarFrame()
294 {
295     std::vector<std::string> params;
296     std::string slideCmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_SCROLL_ANIMATION);
297     std::string otherCmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_JANK);
298     std::string curRadar = "";
299     const std::string splitStr = "{";
300     std::promise<std::string> slidePromise;
301     std::promise<std::string> otherPromise;
302     std::future<std::string> slideResult = slidePromise.get_future();
303     std::future<std::string> otherResult = otherPromise.get_future();
304     std::thread slideThread([&slideCmd, &slidePromise]() {
305         slidePromise.set_value(ExecuteCommand(slideCmd));
306     });
307     std::thread otherThread([&otherCmd, &otherPromise]() {
308         otherPromise.set_value(ExecuteCommand(otherCmd));
309     });
310     slideThread.join();
311     otherThread.join();
312     std::string slideValue = slideResult.get();
313     std::string otherValue = otherResult.get();
314     if (!otherValue.empty()) {
315         curRadar = otherValue;
316     } else {
317         curRadar = slideValue;
318     }
319     StrSplit(curRadar, splitStr, params);
320     for (auto param : params) {
321         if (param.find("LAUNCHER_APP_LAUNCH") != std::string::npos) {
322             curRadar = param;
323             break;
324         }
325     }
326     LOGD("GetRadarFrame::curRadar: %s", curRadar.c_str());
327     return curRadar;
328 }
GetRadarResponse()329 std::string SPUtils::GetRadarResponse()
330 {
331     std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_RESPONSE);
332     std::string curRadar = "";
333     LoadCmd(cmd, curRadar);
334     return curRadar;
335 }
GetRadarComplete()336 std::string SPUtils::GetRadarComplete()
337 {
338     std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_COMPLETED);
339     std::string curRadar = "";
340     LoadCmd(cmd, curRadar);
341     return curRadar;
342 }
343 
GetDeviceInfoMap()344 std::string SPUtils::GetDeviceInfoMap()
345 {
346     std::map<std::string, std::string> deviceInfoMap;
347     deviceInfoMap.merge(GetCpuInfo(false));
348     deviceInfoMap.merge(GetGpuInfo(false));
349     deviceInfoMap.merge(GetDeviceInfo());
350 
351     std::string screenInfos = GetScreen();
352     size_t pos = screenInfos.find(": ");
353     size_t pos1 = screenInfos.find(",");
354     size_t len = 2;
355     std::string screenSize = screenInfos.substr(pos + len, pos1 - pos - len);
356     deviceInfoMap["activeMode"] = screenSize;
357     for (auto iter = deviceInfoMap.cbegin(); iter != deviceInfoMap.cend(); ++iter) {
358         printf("%s: %s\n", iter->first.c_str(), iter->second.c_str());
359     }
360     std::cout << std::endl;
361     return std::string("command exec finished!");
362 }
363 
GetDeviceInfo()364 std::map<std::string, std::string> SPUtils::GetDeviceInfo()
365 {
366     std::map<std::string, std::string> resultMap;
367     resultMap["sn"] = OHOS::system::GetParameter((DEVICE_CMD_MAP.at(DeviceCmd::SN)), "Unknown");
368     resultMap["deviceTypeName"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::DEVICET_NAME), "Unknown");
369     resultMap["brand"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::BRAND), "Unknown");
370     resultMap["board"] = GetProductName();
371     resultMap["version"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::VERSION), "Unknown");
372     resultMap["abilist"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::ABILIST), "Unknown");
373     resultMap["name"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::NAME), "Unknown");
374     resultMap["model"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::MODEL), "Unknown");
375     resultMap["fullname"] = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::FULL_NAME), "Unknown");
376     resultMap["daemonPerfVersion"] = SMART_PERF_VERSION;
377     return resultMap;
378 }
GetCpuInfo(bool isTcpMessage)379 std::map<std::string, std::string> SPUtils::GetCpuInfo(bool isTcpMessage)
380 {
381     std::string clusterNames;
382     std::vector<std::string> policyFiles;
383     std::map<std::string, std::string> resultMap;
384     std::string basePath = "/sys/devices/system/cpu/cpufreq/";
385     DIR *dir = opendir(basePath.c_str());
386     if (dir == nullptr) {
387         return resultMap;
388     }
389     while (true) {
390         struct dirent *ptr = readdir(dir);
391         if (ptr == nullptr) {
392             break;
393         }
394         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
395             continue;
396         }
397         std::string clusterName = std::string(ptr->d_name);
398         if (!isTcpMessage) {
399             clusterNames += clusterName + " ";
400             resultMap["cpu_cluster_name"] = clusterNames;
401         }
402         policyFiles.push_back(IncludePathDelimiter(basePath) + clusterName);
403     }
404     closedir(dir);
405     for (size_t i = 0; i < policyFiles.size(); i++) {
406         std::string cpus;
407         LoadFile(policyFiles[i] + "/affected_cpus", cpus);
408         std::string max;
409         LoadFile(policyFiles[i] + "/cpuinfo_max_freq", max);
410         std::string min;
411         LoadFile(policyFiles[i] + "/cpuinfo_min_freq", min);
412         std::string nameBase;
413         if (!isTcpMessage) {
414             nameBase = "cpu_c" + std::to_string(i + 1) + "_";
415         } else {
416             nameBase = "cpu-c" + std::to_string(i + 1) + "-";
417         }
418         resultMap[nameBase + "cluster"] = cpus;
419         resultMap[nameBase + "max"] = max;
420         resultMap[nameBase + "min"] = min;
421     }
422     return resultMap;
423 }
GetGpuInfo(bool isTcpMessage)424 std::map<std::string, std::string> SPUtils::GetGpuInfo(bool isTcpMessage)
425 {
426     const std::vector<std::string> gpuCurFreqPaths = {
427         "/sys/class/devfreq/fde60000.gpu/",
428         "/sys/class/devfreq/gpufreq/",
429     };
430     std::map<std::string, std::string> resultMap;
431     for (auto& path : gpuCurFreqPaths) {
432         if (FileAccess(path)) {
433             std::string max;
434             SPUtils::LoadFile(path + "/max_freq", max);
435             std::string min;
436             SPUtils::LoadFile(path + "/min_freq", min);
437             resultMap["gpu_max_freq"] = max;
438             resultMap["gpu_min_freq"] = min;
439         }
440     }
441     return resultMap;
442 }
443 
RemoveSpace(std::string & str)444 void SPUtils::RemoveSpace(std::string &str)
445 {
446     int len = 0;
447 
448     for (size_t i = 0; i < str.length(); i++) {
449         if (str[i] != ' ') {
450             break;
451         }
452 
453         ++len;
454     }
455 
456     if (len > 0) {
457         str = str.substr(len);
458     }
459 
460     len = 0;
461     for (size_t i = str.length(); i > 0; --i) {
462         if (str[i - 1] != ' ') {
463             break;
464         }
465 
466         ++len;
467     }
468 
469     if (len > 0) {
470         for (int i = 0; i < len; i++) {
471             str.pop_back();
472         }
473     }
474 }
475 
476 
IntegerVerification(const std::string & str,std::string & errorInfo)477 bool SPUtils::IntegerVerification(const std::string& str, std::string& errorInfo)
478 {
479     uint64_t dest = 0;
480     bool isValid = false;
481 
482     if (str.empty()) {
483         errorInfo = "option requires an argument";
484         LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
485         return false;
486     }
487     if (str.length() > INT_MAX_LEN) {
488         errorInfo = "invalid option parameters";
489         LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
490         return false;
491     }
492 
493     for (size_t i = 0; i < str.length(); i++) {
494         if (str[i] < '0' || str[i] > '9') {
495             errorInfo = "invalid option parameters";
496             LOGE("sour(%s) error(%s)", str.c_str(), errorInfo.c_str());
497             return false;
498         }
499 
500         if (!isValid && (str[i] == '0')) {
501             continue;
502         }
503 
504         isValid = true;
505         dest *= UI_DECIMALISM;
506         dest += (str[i] - CHAR_NUM_DIFF);
507     }
508 
509     if (dest == 0 || dest > INT_MAX) {
510         errorInfo = "option parameter out of range";
511         LOGE("sour(%s) dest(%u) error(%s)", str.c_str(), dest, errorInfo.c_str());
512         return false;
513     }
514 
515     return true;
516 }
517 
VeriyParameter(std::set<std::string> & keys,const std::string & param,std::string & errorInfo)518 bool SPUtils::VeriyParameter(std::set<std::string> &keys, const std::string& param, std::string &errorInfo)
519 {
520     std::vector<std::string> out;
521     std::map<std::string, std::string> mapInfo;
522 
523     if (!IsInvalidInputfromComParam(param, errorInfo)) {
524         LOGE("%s", errorInfo.c_str());
525         return false;
526     }
527 
528     SPUtils::StrSplit(param, "-", out);
529     if (!RemSpaceAndTraPara(out, mapInfo, errorInfo)) {
530         LOGE("%s", errorInfo.c_str());
531         return false;
532     }
533 
534     if (!VeriyKey(keys, mapInfo, errorInfo)) {
535         LOGE("%s", errorInfo.c_str());
536         return false;
537     }
538 
539     if (!VerifyValueStr(mapInfo, errorInfo)) {
540         LOGE("%s", errorInfo.c_str());
541         return false;
542     }
543 
544     if (!IntegerValueVerification(keys, mapInfo, errorInfo)) {
545         LOGE("%s", errorInfo.c_str());
546         return false;
547     }
548     return true;
549 }
550 
IsInvalidInputfromComParam(const std::string & param,std::string & errorInfo)551 bool SPUtils::IsInvalidInputfromComParam(const std::string& param, std::string &errorInfo)
552 {
553     if (param.empty()) {
554         errorInfo = "The parameter cannot be empty";
555         return false;
556     }
557     if (param.find("-PKG") != std::string::npos &&
558         param.find("-PID") != std::string::npos) {
559         LOGE("-PKG and -PID cannot be used together with");
560         return false;
561     }
562     const size_t paramLength = 1;
563     if (param.length() == paramLength && param[0] == '-') {
564         errorInfo = "invalid parameter -- '" + param + "'";
565         return false;
566     }
567     std::string commandShell;
568     for (const auto& a : COMMAND_SHELL_MAP) {
569         commandShell = a.first.substr(1);
570     }
571     if (param.find("--") != std::string::npos && param.find(commandShell)) {
572         errorInfo = "invalid parameter -- '" + param + "'";
573         return false;
574     }
575     return true;
576 }
577 
RemSpaceAndTraPara(std::vector<std::string> & outParam,std::map<std::string,std::string> & mapInfo,std::string & errorInfo)578 bool SPUtils::RemSpaceAndTraPara(std::vector<std::string>& outParam, std::map<std::string, std::string>& mapInfo,
579     std::string &errorInfo)
580 {
581     std::string keyParam;
582     std::string valueParm;
583     std::vector<std::string> subOut;
584 
585     for (auto it = outParam.begin(); it != outParam.end(); ++it) { // Parsing keys and values
586         subOut.clear();
587         SPUtils::StrSplit(*it, " ", subOut);
588         if (mapInfo.end() != mapInfo.find(subOut[0])) {
589             errorInfo = "duplicate parameters -- '" + subOut[0] + "'";
590             return false;
591         }
592 
593         if (subOut.size() >= UI_INDEX_2) {
594             keyParam = subOut[0];
595             valueParm = subOut[1];
596             SPUtils::RemoveSpace(keyParam);
597             SPUtils::RemoveSpace(valueParm);
598             mapInfo[keyParam] = valueParm;
599         } else if (subOut.size() >= 1) {
600             keyParam = subOut[0];
601             SPUtils::RemoveSpace(keyParam);
602             mapInfo[keyParam] = "";
603         }
604     }
605     return true;
606 }
607 
VeriyKey(std::set<std::string> & keys,std::map<std::string,std::string> & mapInfo,std::string & errorInfo)608 bool SPUtils::VeriyKey(std::set<std::string> &keys, std::map<std::string, std::string> &mapInfo,
609     std::string &errorInfo)
610 {
611     for (auto it = mapInfo.begin(); it != mapInfo.end(); ++it) {
612         if (keys.end() == keys.find(it->first)) {
613             errorInfo = "invalid parameter -- '" + it->first + "'";
614             return false;
615         }
616     }
617 
618     return true;
619 }
620 
VerifyValueStr(std::map<std::string,std::string> & mapInfo,std::string & errorInfo)621 bool SPUtils::VerifyValueStr(std::map<std::string, std::string> &mapInfo, std::string &errorInfo)
622 {
623     auto a = mapInfo.find("VIEW");
624     if (mapInfo.end() != a && a->second.empty()) { // Cannot be null
625         errorInfo += "option requires an argument -- '" + a->first + "'";
626         return false;
627     }
628     a = mapInfo.find("PKG");
629     if (mapInfo.end() != a && a->second.empty()) { // Cannot be null
630         errorInfo += "option requires an argument -- '" + a->first + "'";
631         return false;
632     }
633     a = mapInfo.find("PID");
634     if (mapInfo.end() != a && a->second.empty()) { // Cannot be null
635         errorInfo += "option requires an argument -- '" + a->first + "'";
636         return false;
637     }
638     a = mapInfo.find("OUT");
639     if (mapInfo.end() != a) {
640         if (a->second.empty()) {
641             errorInfo += "option requires an argument -- '" + a->first + "'";
642             return false;
643         }
644         // The total length of file path and name cannot exceed PATH_MAX
645         if (a->second.length() >= PATH_MAX) {
646             errorInfo +=
647                 "invalid parameter, file path cannot exceed " + std::to_string(PATH_MAX) + " -- '" + a->first + "'";
648             return false;
649         }
650         size_t pos = a->second.rfind('/');
651         if (pos == a->second.length()) { // not file name
652             errorInfo += "invalid parameter,not file name -- '" + a->first + "'";
653             return false;
654         }
655         if (std::string::npos != pos &&
656             (!SPUtils::FileAccess(a->second.substr(0, pos)))) { // determine if the directory exists
657             errorInfo += "invalid parameter,file path not found -- '" + a->first + "'";
658             return false;
659         }
660         std::string outStr = a->second;
661         std::vector<std::string> outList;
662         SPUtils::StrSplit(outStr, "/", outList);
663         for (auto it = outList.begin(); outList.end() != it; ++it) {
664             if ((*it).length() >= NAME_MAX) {
665                 errorInfo += "invalid parameter, file directory or name cannot exceed 255 -- '" + a->first + "'";
666                 return false;
667             }
668         }
669     }
670     return true;
671 }
672 
IntegerValueVerification(std::set<std::string> & keys,std::map<std::string,std::string> & mapInfo,std::string & errorInfo)673 bool SPUtils::IntegerValueVerification(std::set<std::string> &keys, std::map<std::string, std::string> &mapInfo,
674     std::string &errorInfo)
675 {
676     std::vector<std::string> integerCheck; // Number of integers to be detected
677 
678     if (keys.end() != keys.find("N")) {
679         integerCheck.push_back("N");
680     }
681     if (keys.end() != keys.find("fl")) {
682         integerCheck.push_back("fl");
683     }
684     if (keys.end() != keys.find("ftl")) {
685         integerCheck.push_back("ftl");
686     }
687     if (keys.end() != keys.find("PID")) {
688         integerCheck.push_back("PID");
689     }
690 
691     for (auto it = integerCheck.begin(); it != integerCheck.end(); ++it) {
692         auto a = mapInfo.find(*it);
693         if (mapInfo.end() != a) {
694             if (a->second.empty()) {
695                 errorInfo += "option requires an argument -- '" + a->first + "'";
696                 return false;
697             }
698             if (!SPUtils::IntegerVerification(a->second, errorInfo)) {
699                 errorInfo += "option parameter out of range -- '" + a->first + "'";
700                 return false;
701             }
702         }
703     }
704 
705     return true;
706 }
707 
IsHmKernel()708 bool SPUtils::IsHmKernel()
709 {
710     bool isHM = false;
711     utsname unameBuf;
712     if ((uname(&unameBuf)) == 0) {
713         std::string osRelease = unameBuf.release;
714         isHM = osRelease.find("HongMeng") != std::string::npos;
715     }
716     return isHM;
717 }
718 
GetCpuNum()719 std::string SPUtils::GetCpuNum()
720 {
721     std::string cpuCores = "cpuCores||";
722     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
723     CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
724     std::vector<CpuFreq> &cpufreq = result.data;
725     size_t cpuNum = cpufreq.size();
726     cpuCores += std::to_string(cpuNum);
727     if (cpuNum == 0) {
728         std::cout << "CPU frequency collection failed." << std::endl;
729         LOGE("CPU frequency collection failed.");
730     }
731     return cpuCores;
732 }
GetCurrentTime(int prevTime)733 void SPUtils::GetCurrentTime(int prevTime)
734 {
735     LOGD("SPUtils::prevTime (%d)", prevTime);
736     unsigned long sleepNowTime = 10000;
737     bool shouldContinue = true;
738     while (shouldContinue) {
739         struct timespec time1 = { 0 };
740         clock_gettime(CLOCK_MONOTONIC, &time1);
741         int curTimeNow = static_cast<int>(time1.tv_sec - 1);
742         if (curTimeNow == prevTime) {
743             usleep(sleepNowTime);
744         } else {
745             shouldContinue = false;
746         }
747     }
748 }
749 
IsForeGround(const std::string & pkg)750 bool SPUtils::IsForeGround(const std::string &pkg)
751 {
752     bool isFoundAppName = false;
753     bool isForeground = false;
754     std::string result;
755     const std::string cmd = "hidumper -s AbilityManagerService -a -l";
756     if (cmd.empty()) {
757         LOGI("cmd is null");
758         return false;
759     }
760 
761     FILE *fd = popen(cmd.c_str(), "r");
762     if (fd == nullptr) {
763         return false;
764     }
765     size_t bytesRead;
766     std::array<char, BUFFER_SIZE> buf;
767     while ((bytesRead = fread(buf.data(), 1, buf.size(), fd)) > 0) {
768         result.append(buf.data(), bytesRead);
769     }
770     if (pclose(fd) == -1) {
771         LOGE("Error: failed to close file");
772         return false;
773     }
774 
775     std::istringstream iss(result);
776     std::string line;
777     while (std::getline(iss, line)) {
778         if (!isFoundAppName && line.find("mission name #[#" + pkg) != std::string::npos) {
779             isFoundAppName = true;
780         }
781         if (isFoundAppName) {
782             if (line.find("app state") != std::string::npos) {
783                 isForeground = IsFindForeGround(line);
784                 break;
785             }
786         }
787     }
788     return isForeground;
789 }
790 
IsFindForeGround(const std::string & line)791 bool SPUtils::IsFindForeGround(const std::string &line)
792 {
793     return line.find("FOREGROUND") != std::string::npos;
794 }
795 
IsFindAbilist()796 bool SPUtils::IsFindAbilist()
797 {
798     std::string abilist = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::ABILIST), "Unknown");
799     std::string brand = OHOS::system::GetParameter(DEVICE_CMD_MAP.at(DeviceCmd::BRAND), "Unknown");
800     if (abilist.find("arm") != std::string::npos && brand.find("HUA") != std::string::npos) {
801         return true;
802     } else if (abilist.find("arm") != std::string::npos && brand.find("HUA") == std::string::npos) {
803         return OHOS::SmartPerf::FPS::GetInstance().SetOtherDeviceFlag();
804     } else {
805         return false;
806     }
807 }
SetRkFlag()808 void SPUtils::SetRkFlag()
809 {
810     bool findAbilistResult = IsFindAbilist();
811     if (!findAbilistResult) {
812         OHOS::SmartPerf::FPS::GetInstance().SetRkFlag();
813         OHOS::SmartPerf::Power::GetInstance().SetRkFlag();
814         OHOS::SmartPerf::GPU::GetInstance().SetRkFlag();
815         OHOS::SmartPerf::DDR::GetInstance().SetRkFlag();
816     }
817 }
GetPathPermissions(const std::string & path)818 bool SPUtils::GetPathPermissions(const std::string &path)
819 {
820     const std::string dataCsv = "/data/local/tmp/data.csv";
821     const std::string indexInfoCsv = "/data/local/tmp/smartperf/1/t_index_info.csv";
822     int isDataCsv = strcmp(path.c_str(), dataCsv.c_str());
823     int isIndexInfoCsv = strcmp(path.c_str(), indexInfoCsv.c_str());
824     if (!path.empty()) {
825         std::string cmdResult;
826         std::string cmd;
827         if (isDataCsv == 0 || isIndexInfoCsv == 0) {
828             cmd = "ls -l " + path;
829             LoadCmd(cmd, cmdResult);
830             std::string result = cmdResult.substr(0, 10);
831             return result == "-rw-r--r--";
832         } else {
833             LOGE("the path is false");
834             return false;
835         }
836     } else {
837         LOGE("THE path is empty");
838         return false;
839     }
840 }
841 
GetIsGameApp(const std::string & pkg)842 bool SPUtils::GetIsGameApp(const std::string& pkg)
843 {
844     bool isGame = false;
845     const std::string cmd = "hidumper -s 66006 -a '-t " + pkg + "'";
846     LOGD("SPUtils::GetIsGameApp cmd (%s)", cmd.c_str());
847     FILE *fd = popen(cmd.c_str(), "r");
848     if (fd == nullptr) {
849         LOGD("FPS::fd is empty");
850         return false;
851     }
852     char buf[1024] = {'\0'};
853     while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
854         std::string line(buf);
855         if (line.find("---") != std::string::npos || line.length() <= 1) {
856             continue;
857         }
858         if (line.find("bundleName unknown") != std::string::npos) {
859             isGame = IsFindDHGame(pkg);
860             break;
861         } else {
862             std::vector<std::string> params;
863             SPUtils::StrSplit(line, " ", params);
864             if (params[0] == "1" && params[1] == pkg) {
865                 isGame = true;
866                 LOGD("SPUtils::GetIsGameApp isGame", isGame);
867                 break;
868             }
869         }
870     }
871     if (pclose(fd) == -1) {
872         LOGE("SPUtils::IsGameApp Error Failed to close file");
873     }
874     return isGame;
875 }
GetVersion()876 std::string SPUtils::GetVersion()
877 {
878     return SMART_PERF_VERSION;
879 }
880 
GetTtyDeviceFd()881 int& SPUtils::GetTtyDeviceFd()
882 {
883     static int fd = dup(STDERR_FILENO);
884     return fd;
885 }
886 
GetTestsaPlugin(int command)887 void SPUtils::GetTestsaPlugin(int command)
888 {
889     #ifdef ARKTEST_ENABLE
890     //Call the function
891     std::string stopJsonString = "{\"command\": \"stopCollect\"}";
892     OHOS::testserver::TestServerClient::GetInstance().SpDaemonProcess(command, stopJsonString);
893     #endif
894 }
895 
KillStartDaemon()896 void SPUtils::KillStartDaemon()
897 {
898     std::string pidCmd = "ps -ef | grep SP_daemon";
899     std::string cmdResult = "";
900     OHOS::SmartPerf::SPUtils::LoadCmd(pidCmd, cmdResult);
901     if (cmdResult.find("testserver") != std::string::npos) {
902         int command = 2;
903         GetTestsaPlugin(command);
904     }
905 }
906 
CreateDir(const std::string & dirPath)907 void SPUtils::CreateDir(const std::string &dirPath)
908 {
909     if (!SPUtils::FileAccess(dirPath)) {
910         std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::CREAT_DIR) + dirPath;
911         std::string cmdResult;
912         if (!SPUtils::LoadCmd(cmd, cmdResult)) {
913             WLOGE("%s capture not be created!", dirPath.c_str());
914         } else {
915             WLOGI("%s created successfully!", dirPath.c_str());
916             return;
917         }
918 
919         std::string chmodCmd = "chmod 777 " + dirPath;
920         std::string chmodResult;
921         if (!SPUtils::LoadCmd(chmodCmd, chmodResult)) {
922             WLOGE("Failed to chmod %s", dirPath.c_str());
923         }
924     }
925 }
926 
RemoveDirOrFile(const std::string & dirPath)927 void SPUtils::RemoveDirOrFile(const std::string &dirPath)
928 {
929     char pathChar[PATH_MAX] = {0x00};
930     if ((realpath(dirPath.c_str(), pathChar) == nullptr)) {
931         WLOGI("%s is not exist.", dirPath.c_str());
932         return;
933     }
934     LOGD("%s is exist, remove...", dirPath.c_str());
935 
936     std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::REMOVE) + dirPath;
937     std::string cmdResult;
938     if (!SPUtils::LoadCmd(cmd, cmdResult)) {
939         WLOGE("%s capture not be removed!", dirPath.c_str());
940     } else {
941         WLOGI("%s removed successfully!", dirPath.c_str());
942     }
943 }
944 
CopyFiles(const std::string & cpStr)945 void SPUtils::CopyFiles(const std::string& cpStr)
946 {
947     std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::CP) + cpStr;
948     std::string cmdResult;
949     if (!SPUtils::LoadCmd(cmd, cmdResult)) {
950         WLOGE("Failed to copy files: %s", cpStr.c_str());
951     }
952 }
953 
TarFiles(const std::string & tarStr)954 void SPUtils::TarFiles(const std::string& tarStr)
955 {
956     std::string tarCommand = CMD_COMMAND_MAP.at(CmdCommand::TAR) + tarStr;
957     std::string cmdResult;
958     if (!SPUtils::LoadCmd(tarCommand, cmdResult)) {
959         WLOGE("Failed to tar log files");
960     }
961 }
962 
GetFileSize(std::string filePath)963 size_t SPUtils::GetFileSize(std::string filePath)
964 {
965     struct stat statbuf;
966     if (stat(filePath.c_str(), &statbuf) == -1) {
967         LOGE("Failed to get file size for %s", filePath.c_str());
968         return 0;
969     }
970     return static_cast<size_t>(statbuf.st_size);
971 }
972 
IsFindDHGame(const std::string & pkg)973 bool SPUtils::IsFindDHGame(const std::string &pkg)
974 {
975     bool isdhGame = false;
976     const std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE);
977     char buf[1024] = {'\0'};
978     FILE *fd = popen(dumperSurface.c_str(), "r");
979     if (fd == nullptr) {
980         return isdhGame;
981     }
982     while (fgets(buf, sizeof(buf), fd) != nullptr) {
983         std::string line = buf;
984         if (line.find(pkg) != std::string::npos || line.find("ShellAssistantAnco") != std::string::npos) {
985             isdhGame = true;
986             break;
987         }
988     }
989     pclose(fd);
990     return isdhGame;
991 }
992 
GetSurface()993 std::string SPUtils::GetSurface()
994 {
995     std::string cmdResult;
996     std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE);
997     LoadCmd(dumperSurface, cmdResult);
998     size_t positionLeft = cmdResult.find("[");
999     size_t positionRight = cmdResult.find("]");
1000     size_t positionNum = 1;
1001     return cmdResult.substr(positionLeft + positionNum, positionRight - positionLeft - positionNum);
1002 }
1003 
GetProductName()1004 std::string SPUtils::GetProductName()
1005 {
1006     return PRODUCT_NAME;
1007 }
1008 }
1009 }
1010