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