1 /*
2 * Copyright (c) 2021-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
16 #include "entities/cpu_entity.h"
17
18 #include "battery_stats_service.h"
19 #include "stats_log.h"
20
21 namespace OHOS {
22 namespace PowerMgr {
23 namespace {
24 auto g_statsService = DelayedStatsSpSingleton<BatteryStatsService>::GetInstance();
25 }
26
CpuEntity()27 CpuEntity::CpuEntity()
28 {
29 STATS_HILOGD(COMP_SVC, "Created cpu entity");
30 consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_CPU;
31 if (!cpuReader_) {
32 cpuReader_ = std::make_shared<CpuTimeReader>();
33 cpuReader_->Init();
34 }
35 }
36
GetCpuTimeMs(int32_t uid)37 int64_t CpuEntity::GetCpuTimeMs(int32_t uid)
38 {
39 int64_t cpuTimeMs = StatsUtils::DEFAULT_VALUE;
40 auto iter = cpuTimeMap_.find(uid);
41 if (iter != cpuTimeMap_.end()) {
42 STATS_HILOGD(COMP_SVC, "Get cpu time: %{public}sms for uid: %{public}d",
43 std::to_string(cpuTimeMs).c_str(), uid);
44 cpuTimeMs = iter->second;
45 } else {
46 STATS_HILOGD(COMP_SVC, "No cpu time realted to uid: %{public}d was found, return 0", uid);
47 }
48 return cpuTimeMs;
49 }
50
UpdateCpuTime()51 void CpuEntity::UpdateCpuTime()
52 {
53 if (cpuReader_) {
54 if (!cpuReader_->UpdateCpuTime()) {
55 STATS_HILOGE(COMP_SVC, "Update CPU time failed");
56 }
57 } else {
58 STATS_HILOGW(COMP_SVC, "CPU reader is nullptr");
59 }
60 }
61
Calculate(int32_t uid)62 void CpuEntity::Calculate(int32_t uid)
63 {
64 double cpuTotalPowerMah = StatsUtils::DEFAULT_VALUE;
65 // Get cpu time related with uid
66 std::vector<int64_t> cpuTimeVec = cpuReader_->GetUidCpuTimeMs(uid);
67 int64_t cpuTimeMs = StatsUtils::DEFAULT_VALUE;
68 for (uint32_t i = 0; i < cpuTimeVec.size(); i++) {
69 cpuTimeMs += cpuTimeVec[i];
70 }
71 auto cpuTimeIter = cpuTimeMap_.find(uid);
72 if (cpuTimeIter != cpuTimeMap_.end()) {
73 STATS_HILOGD(COMP_SVC, "Update cpu time: %{public}sms for uid: %{public}d",
74 std::to_string(cpuTimeMs).c_str(), uid);
75 cpuTimeIter->second = cpuTimeMs;
76 } else {
77 STATS_HILOGD(COMP_SVC, "Create cpu time: %{public}sms for uid: %{public}d",
78 std::to_string(cpuTimeMs).c_str(), uid);
79 cpuTimeMap_.insert(std::pair<int32_t, int64_t>(uid, cpuTimeMs));
80 }
81
82 // Calculate cpu active power
83 cpuTotalPowerMah += CalculateCpuActivePower(uid);
84
85 // Calculate cpu cluster power
86 cpuTotalPowerMah += CalculateCpuClusterPower(uid);
87
88 // Calculate cpu speed power
89 cpuTotalPowerMah += CalculateCpuSpeedPower(uid);
90
91 auto cpuTotalIter = cpuTotalPowerMap_.find(uid);
92 if (cpuTotalIter != cpuTotalPowerMap_.end()) {
93 STATS_HILOGD(COMP_SVC, "Update cpu speed power consumption: %{public}lfmAh for uid: %{public}d",
94 cpuTotalPowerMah, uid);
95 cpuTotalIter->second = cpuTotalPowerMah;
96 } else {
97 STATS_HILOGD(COMP_SVC, "Create cpu speed power consumption: %{public}lfmAh for uid: %{public}d",
98 cpuTotalPowerMah, uid);
99 cpuTotalPowerMap_.insert(std::pair<int32_t, double>(uid, cpuTotalPowerMah));
100 }
101 }
102
CalculateCpuActivePower(int32_t uid)103 double CpuEntity::CalculateCpuActivePower(int32_t uid)
104 {
105 double cpuActiveAverageMa =
106 g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_CPU_ACTIVE);
107 int64_t cpuActiveTimeMs = cpuReader_->GetUidCpuActiveTimeMs(uid);
108 double cpuActivePower = cpuActiveAverageMa * cpuActiveTimeMs / StatsUtils::MS_IN_HOUR;
109
110 auto cpuActiveIter = cpuActivePowerMap_.find(uid);
111 if (cpuActiveIter != cpuActivePowerMap_.end()) {
112 STATS_HILOGD(COMP_SVC, "Update cpu active power consumption: %{public}lfmAh for uid: %{public}d",
113 cpuActivePower, uid);
114 cpuActiveIter->second = cpuActivePower;
115 } else {
116 STATS_HILOGD(COMP_SVC, "Create cpu active power consumption: %{public}lfmAh for uid: %{public}d",
117 cpuActivePower, uid);
118 cpuActivePowerMap_.insert(std::pair<int32_t, double>(uid, cpuActivePower));
119 }
120 return cpuActivePower;
121 }
122
CalculateCpuClusterPower(int32_t uid)123 double CpuEntity::CalculateCpuClusterPower(int32_t uid)
124 {
125 double cpuClusterPower = StatsUtils::DEFAULT_VALUE;
126 for (uint16_t i = 0; i < g_statsService->GetBatteryStatsParser()->GetClusterNum(); i++) {
127 double cpuClusterAverageMa =
128 g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_CPU_CLUSTER, i);
129 int64_t cpuClusterTimeMs = cpuReader_->GetUidCpuClusterTimeMs(uid, i);
130 cpuClusterPower += cpuClusterAverageMa * cpuClusterTimeMs / StatsUtils::MS_IN_HOUR;
131 }
132 auto cpuClusterIter = cpuClusterPowerMap_.find(uid);
133 if (cpuClusterIter != cpuClusterPowerMap_.end()) {
134 STATS_HILOGD(COMP_SVC, "Update cpu cluster power consumption: %{public}lfmAh for uid: %{public}d",
135 cpuClusterPower, uid);
136 cpuClusterIter->second = cpuClusterPower;
137 } else {
138 STATS_HILOGD(COMP_SVC, "Create cpu cluster power consumption: %{public}lfmAh for uid: %{public}d",
139 cpuClusterPower, uid);
140 cpuClusterPowerMap_.insert(std::pair<int32_t, double>(uid, cpuClusterPower));
141 }
142 return cpuClusterPower;
143 }
144
CalculateCpuSpeedPower(int32_t uid)145 double CpuEntity::CalculateCpuSpeedPower(int32_t uid)
146 {
147 double cpuSpeedPower = StatsUtils::DEFAULT_VALUE;
148 for (uint16_t i = 0; i < g_statsService->GetBatteryStatsParser()->GetClusterNum(); i++) {
149 for (uint16_t j = 0; j < g_statsService->GetBatteryStatsParser()->GetSpeedNum(i); j++) {
150 STATS_HILOGD(COMP_SVC, "Calculate cluster: %{public}d, speed: %{public}d", j, i);
151 std::string statType = StatsUtils::CURRENT_CPU_SPEED + std::to_string(i);
152 double cpuSpeedAverageMa = g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(statType, j);
153 int64_t cpuSpeedTimeMs = cpuReader_->GetUidCpuFreqTimeMs(uid, i, j);
154 cpuSpeedPower += cpuSpeedAverageMa * cpuSpeedTimeMs / StatsUtils::MS_IN_HOUR;
155 }
156 }
157 auto cpuSpeedIter = cpuSpeedPowerMap_.find(uid);
158 if (cpuSpeedIter != cpuSpeedPowerMap_.end()) {
159 STATS_HILOGD(COMP_SVC, "Update cpu speed power consumption: %{public}lfmAh for uid: %{public}d",
160 cpuSpeedPower, uid);
161 cpuSpeedIter->second = cpuSpeedPower;
162 } else {
163 STATS_HILOGD(COMP_SVC, "Create cpu speed power consumption: %{public}lfmAh for uid: %{public}d",
164 cpuSpeedPower, uid);
165 cpuSpeedPowerMap_.insert(std::pair<int32_t, double>(uid, cpuSpeedPower));
166 }
167 return cpuSpeedPower;
168 }
169
GetEntityPowerMah(int32_t uidOrUserId)170 double CpuEntity::GetEntityPowerMah(int32_t uidOrUserId)
171 {
172 double power = StatsUtils::DEFAULT_VALUE;
173 auto iter = cpuTotalPowerMap_.find(uidOrUserId);
174 if (iter != cpuTotalPowerMap_.end()) {
175 power = iter->second;
176 STATS_HILOGD(COMP_SVC, "Get app cpu total power consumption: %{public}lfmAh for uid: %{public}d",
177 power, uidOrUserId);
178 } else {
179 STATS_HILOGD(COMP_SVC,
180 "No app cpu total power consumption related to uid: %{public}d was found, return 0", uidOrUserId);
181 }
182 return power;
183 }
184
GetStatsPowerMah(StatsUtils::StatsType statsType,int32_t uid)185 double CpuEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid)
186 {
187 double power = StatsUtils::DEFAULT_VALUE;
188
189 if (statsType == StatsUtils::STATS_TYPE_CPU_ACTIVE) {
190 auto cpuActiveIter = cpuActivePowerMap_.find(uid);
191 if (cpuActiveIter != cpuActivePowerMap_.end()) {
192 power = cpuActiveIter->second;
193 STATS_HILOGD(COMP_SVC, "Get cpu active power consumption: %{public}lfmAh for uid: %{public}d",
194 power, uid);
195 } else {
196 STATS_HILOGD(COMP_SVC,
197 "No cpu active power consumption related to uid: %{public}d was found, return 0", uid);
198 }
199 } else if (statsType == StatsUtils::STATS_TYPE_CPU_CLUSTER) {
200 auto cpuClusterIter = cpuClusterPowerMap_.find(uid);
201 if (cpuClusterIter != cpuClusterPowerMap_.end()) {
202 power = cpuClusterIter->second;
203 STATS_HILOGD(COMP_SVC, "Get cpu cluster power consumption: %{public}lfmAh for uid: %{public}d",
204 power, uid);
205 } else {
206 STATS_HILOGD(COMP_SVC,
207 "No cpu cluster power consumption related to uid: %{public}d was found, return 0", uid);
208 }
209 } else if (statsType == StatsUtils::STATS_TYPE_CPU_SPEED) {
210 auto cpuSpeedIter = cpuSpeedPowerMap_.find(uid);
211 if (cpuSpeedIter != cpuSpeedPowerMap_.end()) {
212 power = cpuSpeedIter->second;
213 STATS_HILOGD(COMP_SVC, "Get cpu speed power consumption: %{public}lfmAh for uid: %{public}d",
214 power, uid);
215 } else {
216 STATS_HILOGD(COMP_SVC,
217 "No cpu speed power consumption related to uid: %{public}d was found, return 0", uid);
218 }
219 }
220 return power;
221 }
222
Reset()223 void CpuEntity::Reset()
224 {
225 // Reset app Cpu time
226 for (auto& iter : cpuTimeMap_) {
227 iter.second = StatsUtils::DEFAULT_VALUE;
228 }
229
230 // Reset app Cpu total power consumption
231 for (auto& iter : cpuTotalPowerMap_) {
232 iter.second = StatsUtils::DEFAULT_VALUE;
233 }
234
235 // Reset app Cpu active power consumption
236 for (auto& iter : cpuActivePowerMap_) {
237 iter.second = StatsUtils::DEFAULT_VALUE;
238 }
239
240 // Reset app Cpu cluster power consumption
241 for (auto& iter : cpuClusterPowerMap_) {
242 iter.second = StatsUtils::DEFAULT_VALUE;
243 }
244
245 // Reset app Cpu speed power consumption
246 for (auto& iter : cpuSpeedPowerMap_) {
247 iter.second = StatsUtils::DEFAULT_VALUE;
248 }
249 }
250
DumpInfo(std::string & result,int32_t uid)251 void CpuEntity::DumpInfo(std::string& result, int32_t uid)
252 {
253 if (cpuReader_) {
254 cpuReader_->DumpInfo(result, uid);
255 }
256 }
257 } // namespace PowerMgr
258 } // namespace OHOS
259