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
16#include "include/CPU.h"
17#include <sstream>
18#include <cstdio>
19#include <unistd.h>
20#include <cstring>
21#include <string>
22#include <iostream>
23#include <climits>
24#include "securec.h"
25#include "include/sp_utils.h"
26#include "cpu_collector.h"
27#include "collect_result.h"
28#include "include/startup_delay.h"
29#include "include/sp_log.h"
30
31using namespace OHOS::HiviewDFX;
32using namespace OHOS::HiviewDFX::UCollectUtil;
33using namespace OHOS::HiviewDFX::UCollect;
34
35namespace OHOS {
36namespace SmartPerf {
37std::map<std::string, std::string> CPU::ItemData()
38{
39    std::map<std::string, std::string> result;
40    std::vector<CpuFreqs> cpuFreqInfo = GetCpuFreq();
41    for (size_t i = 0; i < cpuFreqInfo.size(); i++) {
42        std::string cpuFreqStr = std::to_string(cpuFreqInfo[i].curFreq);
43        std::string cpuId = std::to_string(cpuFreqInfo[i].cpuId);
44        result["cpu" + cpuId + "Frequency"] = cpuFreqStr;
45    }
46    std::vector<CpuUsageInfos> workLoads = GetCpuUsage();
47    const size_t oneHundred = 100;
48    if (workLoads.empty()) {
49        return result;
50    }
51    for (size_t i = 0; i < workLoads.size(); i++) {
52        std::string cpuIdStr = workLoads[i].cpuId;
53        std::string userUsageStr = std::to_string(workLoads[i].userUsage * oneHundred);
54        std::string niceUsageStr = std::to_string(workLoads[i].niceUsage * oneHundred);
55        std::string systemUsageStr = std::to_string(workLoads[i].systemUsage * oneHundred);
56        std::string idleUsageStr = std::to_string(workLoads[i].idleUsage * oneHundred);
57        std::string ioWaitUsageStr = std::to_string(workLoads[i].ioWaitUsage * oneHundred);
58        std::string irqUsageStr = std::to_string(workLoads[i].irqUsage * oneHundred);
59        std::string softIrqUsageStr = std::to_string(workLoads[i].softIrqUsage * oneHundred);
60        std::string totalUsageStr = std::to_string((workLoads[i].userUsage + workLoads[i].niceUsage +
61            workLoads[i].systemUsage + workLoads[i].ioWaitUsage + workLoads[i].irqUsage + workLoads[i].softIrqUsage) *
62            oneHundred);
63        if (cpuIdStr == cpustr) {
64            cpuIdStr = totalcpu;
65        }
66        result[cpuIdStr + "userUsage"] = userUsageStr;
67        result[cpuIdStr + "niceUsage"] = niceUsageStr;
68        result[cpuIdStr + "systemUsage"] = systemUsageStr;
69        result[cpuIdStr + "idleUsage"] = idleUsageStr;
70        result[cpuIdStr + "ioWaitUsage"] = ioWaitUsageStr;
71        result[cpuIdStr + "irqUsage"] = irqUsageStr;
72        result[cpuIdStr + "softIrqUsage"] = softIrqUsageStr;
73        result[cpuIdStr + "Usage"] = totalUsageStr;
74    }
75    if (!packageName.empty() && !hapFlag) {
76        std::map<std::string, std::string> processCpuInfo = CPU::GetSysProcessCpuLoad();
77        if (!processCpuInfo.empty()) {
78            for (auto it = processCpuInfo.begin(); it != processCpuInfo.end(); ++it) {
79                result.insert(*it);
80            }
81        }
82    }
83
84    LOGI("CPU::ItemData map size(%u)", result.size());
85    return result;
86}
87
88void CPU::SetPackageName(const std::string &pName)
89{
90    packageName = pName;
91    LOGI("CPU SetPackageName name(%s)", pName.c_str());
92}
93
94void CPU::SetProcessId(const std::string &pid)
95{
96    processId = pid;
97}
98
99std::vector<CpuFreqs> CPU::GetCpuFreq()
100{
101    OHOS::SmartPerf::CpuFreqs cpuFreqs;
102    std::vector<CpuFreqs> cpuFrequency;
103    std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
104    CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
105    std::vector<CpuFreq> &cpufreq = result.data;
106    for (size_t i = 0; i < cpufreq.size(); i++) {
107        cpuFreqs.cpuId = cpufreq[i].cpuId;
108        cpuFreqs.curFreq = cpufreq[i].curFreq;
109        cpuFrequency.push_back(cpuFreqs);
110        LOGI("cpuFreqs.cpuId: %s", std::to_string(cpufreq[i].cpuId).c_str());
111        LOGI("cpuFreqs.curFreq: %s", std::to_string(cpufreq[i].curFreq).c_str());
112    }
113    return cpuFrequency;
114}
115
116std::vector<CpuUsageInfos> CPU::GetCpuUsage()
117{
118    OHOS::SmartPerf::CpuUsageInfos cpuUsageInfos;
119    std::vector<CpuUsageInfos> workload;
120    std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
121    CollectResult<SysCpuUsage> result = collector->CollectSysCpuUsage(true);
122    SysCpuUsage &sysCpuUsage = result.data;
123    if (sysCpuUsage.cpuInfos.empty()) {
124        return workload;
125    }
126    for (auto &cpuInfo : sysCpuUsage.cpuInfos) {
127        cpuUsageInfos.cpuId = cpuInfo.cpuId;
128        cpuUsageInfos.userUsage = cpuInfo.userUsage;
129        cpuUsageInfos.niceUsage = cpuInfo.niceUsage;
130        cpuUsageInfos.systemUsage = cpuInfo.systemUsage;
131        cpuUsageInfos.idleUsage = cpuInfo.idleUsage;
132        cpuUsageInfos.ioWaitUsage = cpuInfo.ioWaitUsage;
133        cpuUsageInfos.irqUsage = cpuInfo.irqUsage;
134        cpuUsageInfos.softIrqUsage = cpuInfo.softIrqUsage;
135        workload.push_back(cpuUsageInfos);
136        LOGI("UsageCpuId: %s", cpuInfo.cpuId.c_str());
137        LOGI("userUsage: %s", std::to_string(cpuInfo.userUsage).c_str());
138        LOGI("niceUsage: %s", std::to_string(cpuInfo.niceUsage).c_str());
139        LOGI("systemUsage: %s", std::to_string(cpuInfo.systemUsage).c_str());
140        LOGI("idleUsage: %s", std::to_string(cpuInfo.idleUsage).c_str());
141        LOGI("ioWaitUsage: %s", std::to_string(cpuInfo.ioWaitUsage).c_str());
142        LOGI("irqUsage: %s", std::to_string(cpuInfo.irqUsage).c_str());
143        LOGI("softIrqUsage: %s", std::to_string(cpuInfo.softIrqUsage).c_str());
144    }
145    return workload;
146}
147
148std::map<std::string, std::string> CPU::GetSysProcessCpuLoad() const
149{
150    std::map<std::string, std::string> processCpuInfo;
151    const size_t oneHundred = 100;
152    if (!processId.empty()) {
153        int32_t procId = 0;
154        procId = std::stoi(processId);
155        std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
156        auto collectResult = collector->CollectProcessCpuStatInfo(procId, true);
157        auto data = collectResult.data;
158        processCpuInfo["ProcId"] = std::to_string(data.pid);
159        processCpuInfo["ProcAppName"] = data.procName;
160        processCpuInfo["ProcCpuLoad"] = std::to_string(data.cpuLoad * oneHundred);
161        processCpuInfo["ProcCpuUsage"] = std::to_string(data.cpuUsage * oneHundred);
162        processCpuInfo["ProcUCpuUsage"] = std::to_string(data.uCpuUsage * oneHundred);
163        processCpuInfo["ProcSCpuUsage"] = std::to_string(data.sCpuUsage * oneHundred);
164        LOGI("ProcId: %s", std::to_string(data.pid).c_str());
165        LOGI("ProcAppName: %s", data.procName.c_str());
166        LOGI("ProcCpuLoad: %s", std::to_string(data.cpuLoad).c_str());
167        LOGI("ProcCpuUsage: %s", std::to_string(data.cpuUsage).c_str());
168        LOGI("ProcUCpuUsage: %s", std::to_string(data.uCpuUsage).c_str());
169        LOGI("ProcSCpuUsage: %s", std::to_string(data.sCpuUsage).c_str());
170    } else {
171        processCpuInfo["ProcId"] = "NA";
172        processCpuInfo["ProcAppName"] = packageName;
173        processCpuInfo["ProcCpuLoad"] = "NA";
174        processCpuInfo["ProcCpuUsage"] = "NA";
175        processCpuInfo["ProcUCpuUsage"] = "NA";
176        processCpuInfo["ProcSCpuUsage"] = "NA";
177    }
178    if (processCpuInfo.find("ProcAppName") != processCpuInfo.end() && processCpuInfo["ProcAppName"].empty()) {
179        processCpuInfo["ProcId"] = "0";
180        processCpuInfo["ProcAppName"] = packageName;
181        processCpuInfo["ProcCpuLoad"] = "0";
182        processCpuInfo["ProcCpuUsage"] = "0";
183        processCpuInfo["ProcUCpuUsage"] = "0";
184        processCpuInfo["ProcSCpuUsage"] = "0";
185    }
186    return processCpuInfo;
187}
188void CPU::IsFindHap()
189{
190    hapFlag = true;
191}
192}
193}
194