• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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