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