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 "cpu_time_reader.h"
17
18 #include <fstream>
19 #include "string_ex.h"
20
21 #include "battery_stats_service.h"
22 #include "stats_helper.h"
23 #include "stats_log.h"
24 #include "stats_utils.h"
25
26 namespace OHOS {
27 namespace PowerMgr {
28 namespace {
29 static const std::string UID_CPU_ACTIVE_TIME_FILE = "/proc/uid_concurrent_active_time";
30 static const std::string UID_CPU_CLUSTER_TIME_FILE = "/proc/uid_concurrent_policy_time";
31 static const std::string UID_CPU_FREQ_TIME_FILE = "/proc/uid_time_in_state";
32 static const std::string UID_CPU_TIME_FILE = "/proc/uid_cputime/show_uid_stat";
33 } // namespace
Init()34 bool CpuTimeReader::Init()
35 {
36 if (!UpdateCpuTime()) {
37 STATS_HILOGW(COMP_SVC, "Update cpu time failed");
38 }
39 return true;
40 }
41
GetUidCpuActiveTimeMs(int32_t uid)42 int64_t CpuTimeReader::GetUidCpuActiveTimeMs(int32_t uid)
43 {
44 int64_t cpuActiveTime = 0;
45 auto iter = activeTimeMap_.find(uid);
46 if (iter != activeTimeMap_.end()) {
47 cpuActiveTime = iter->second;
48 STATS_HILOGD(COMP_SVC, "Get cpu active time: %{public}s for uid: %{public}d",
49 std::to_string(cpuActiveTime).c_str(), uid);
50 } else {
51 STATS_HILOGD(COMP_SVC, "No cpu active time found for uid: %{public}d, return 0", uid);
52 }
53 return cpuActiveTime;
54 }
55
DumpInfo(std::string & result,int32_t uid)56 void CpuTimeReader::DumpInfo(std::string& result, int32_t uid)
57 {
58 auto uidIter = lastUidTimeMap_.find(uid);
59 if (uidIter == lastUidTimeMap_.end()) {
60 STATS_HILOGE(COMP_SVC, "No related CPU info for uid: %{public}d", uid);
61 return;
62 }
63 std::string freqTime = "";
64 auto freqIter = lastFreqTimeMap_.find(uid);
65 if (freqIter != lastFreqTimeMap_.end()) {
66 for (auto timeIter = freqIter->second.begin(); timeIter != freqIter->second.end(); timeIter++) {
67 for (uint32_t i = 0; i < timeIter->second.size(); i++) {
68 freqTime.append(ToString(timeIter->second[i]))
69 .append(" ");
70 }
71 }
72 }
73 result.append("Total cpu time: userSpaceTime=")
74 .append(ToString(uidIter->second[0]))
75 .append("ms, systemSpaceTime=")
76 .append(ToString(uidIter->second[1]))
77 .append("ms\n")
78 .append("Total cpu time per freq: ")
79 .append(freqTime)
80 .append("\n");
81 }
82
GetUidCpuClusterTimeMs(int32_t uid,uint32_t cluster)83 int64_t CpuTimeReader::GetUidCpuClusterTimeMs(int32_t uid, uint32_t cluster)
84 {
85 int64_t cpuClusterTime = 0;
86 auto iter = clusterTimeMap_.find(uid);
87 if (iter != clusterTimeMap_.end()) {
88 auto cpuClusterTimeVector = iter->second;
89 if (cluster < cpuClusterTimeVector.size()) {
90 cpuClusterTime = cpuClusterTimeVector[cluster];
91 STATS_HILOGD(COMP_SVC, "Get cpu cluster time: %{public}s of cluster: %{public}d",
92 std::to_string(cpuClusterTime).c_str(), cluster);
93 } else {
94 STATS_HILOGD(COMP_SVC, "No cpu cluster time of cluster: %{public}d found, return 0", cluster);
95 }
96 } else {
97 STATS_HILOGD(COMP_SVC, "No cpu cluster time vector found for uid: %{public}d, return 0", uid);
98 }
99 return cpuClusterTime;
100 }
101
GetUidCpuFreqTimeMs(int32_t uid,uint32_t cluster,uint32_t speed)102 int64_t CpuTimeReader::GetUidCpuFreqTimeMs(int32_t uid, uint32_t cluster, uint32_t speed)
103 {
104 int64_t cpuFreqTime = 0;
105 auto uidIter = freqTimeMap_.find(uid);
106 if (uidIter != freqTimeMap_.end()) {
107 auto cpuFreqTimeMap = uidIter->second;
108 auto clusterIter = cpuFreqTimeMap.find(cluster);
109 if (clusterIter != cpuFreqTimeMap.end()) {
110 auto cpuFreqTimeVector = clusterIter->second;
111 if (speed < cpuFreqTimeVector.size()) {
112 cpuFreqTime = cpuFreqTimeVector[speed];
113 STATS_HILOGD(COMP_SVC, "Get cpu freq time: %{public}s of speed: %{public}d",
114 std::to_string(cpuFreqTime).c_str(), speed);
115 } else {
116 STATS_HILOGD(COMP_SVC, "No cpu freq time of speed: %{public}d found, return 0", speed);
117 }
118 } else {
119 STATS_HILOGD(COMP_SVC, "No cluster cpu freq time vector of cluster: %{public}d found, return 0",
120 cluster);
121 }
122 } else {
123 STATS_HILOGD(COMP_SVC, "No uid cpu freq time map found for uid: %{public}d, return 0", uid);
124 }
125 return cpuFreqTime;
126 }
127
GetUidCpuTimeMs(int32_t uid)128 std::vector<int64_t> CpuTimeReader::GetUidCpuTimeMs(int32_t uid)
129 {
130 std::vector<int64_t> cpuTimeVec;
131 auto iter = uidTimeMap_.find(uid);
132 if (iter != uidTimeMap_.end()) {
133 cpuTimeVec = iter->second;
134 STATS_HILOGD(COMP_SVC, "Get uid cpu time vector for uid: %{public}d, size: %{public}d", uid,
135 static_cast<int32_t>(cpuTimeVec.size()));
136 } else {
137 STATS_HILOGD(COMP_SVC, "No uid cpu time vector found for uid: %{public}d, return null", uid);
138 }
139 return cpuTimeVec;
140 }
141
UpdateCpuTime()142 bool CpuTimeReader::UpdateCpuTime()
143 {
144 bool result = true;
145 if (!ReadUidCpuClusterTime()) {
146 STATS_HILOGW(COMP_SVC, "Read uid cpu cluster time failed");
147 result = false;
148 }
149
150 if (!ReadUidCpuTime()) {
151 STATS_HILOGW(COMP_SVC, "Read uid cpu time failed");
152 result = false;
153 }
154
155 if (!ReadUidCpuActiveTime()) {
156 STATS_HILOGW(COMP_SVC, "Read uid cpu active time failed");
157 result = false;
158 }
159
160 if (!ReadUidCpuFreqTime()) {
161 STATS_HILOGW(COMP_SVC, "Read uid cpu freq time failed");
162 result = false;
163 }
164 return result;
165 }
166
ReadUidCpuActiveTimeImpl(std::string & line,int32_t uid)167 bool CpuTimeReader::ReadUidCpuActiveTimeImpl(std::string& line, int32_t uid)
168 {
169 int64_t timeMs = 0;
170 std::vector<std::string> splitedTime;
171 Split(line, ' ', splitedTime);
172 for (uint16_t i = 0; i < splitedTime.size(); i++) {
173 timeMs += stoll(splitedTime[i]) * 10; // Unit is 10ms
174 }
175
176 int64_t increment = 0;
177 if (timeMs > 0) {
178 auto iterLast = lastActiveTimeMap_.find(uid);
179 if (iterLast != lastActiveTimeMap_.end()) {
180 increment = timeMs - iterLast->second;
181 if (increment >= 0) {
182 iterLast->second = timeMs;
183 } else {
184 STATS_HILOGI(COMP_SVC, "Negative cpu active time increment");
185 return false;
186 }
187 } else {
188 lastActiveTimeMap_.insert(std::pair<int32_t, int64_t>(uid, timeMs));
189 increment = timeMs;
190 }
191 }
192
193 if (StatsHelper::IsOnBattery()) {
194 STATS_HILOGD(COMP_SVC, "Power supply is not connected. Add the increment");
195 auto iter = activeTimeMap_.find(uid);
196 if (iter != activeTimeMap_.end()) {
197 iter->second += increment;
198 } else {
199 activeTimeMap_.insert(std::pair<int32_t, int64_t>(uid, increment));
200 STATS_HILOGI(COMP_SVC, "Add active time: %{public}sms, uid: %{public}d",
201 std::to_string(increment).c_str(), uid);
202 }
203 }
204 return true;
205 }
206
ReadUidCpuActiveTime()207 bool CpuTimeReader::ReadUidCpuActiveTime()
208 {
209 std::ifstream input(UID_CPU_ACTIVE_TIME_FILE);
210 if (!input) {
211 STATS_HILOGW(COMP_SVC, "Open file failed");
212 return false;
213 }
214
215 std::string line;
216 const int32_t INDEX_0 = 0;
217 const int32_t INDEX_1 = 1;
218 while (getline(input, line)) {
219 int32_t uid = StatsUtils::INVALID_VALUE;
220 std::vector<std::string> splitedLine;
221 Split(line, ':', splitedLine);
222 if (splitedLine[INDEX_0] == "cpus") {
223 continue;
224 } else {
225 uid = stoi(splitedLine[INDEX_0]);
226 }
227
228 if (uid > StatsUtils::INVALID_VALUE) {
229 auto bss = BatteryStatsService::GetInstance();
230 auto uidEntity =
231 bss->GetBatteryStatsCore()->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
232 if (uidEntity) {
233 uidEntity->UpdateUidMap(uid);
234 }
235 }
236
237 if (ReadUidCpuActiveTimeImpl(splitedLine[INDEX_1], uid)) {
238 continue;
239 } else {
240 return false;
241 }
242 }
243 return true;
244 }
245
ReadPolicy(std::vector<uint16_t> & clusters,std::string & line)246 void CpuTimeReader::ReadPolicy(std::vector<uint16_t>& clusters, std::string& line)
247 {
248 std::vector<std::string> splitedPolicy;
249 Split(line, ' ', splitedPolicy);
250 uint32_t step = 2;
251 for (uint32_t i = 0; i < splitedPolicy.size(); i += step) {
252 uint16_t coreNum = static_cast<uint16_t>(stoi(splitedPolicy[i + 1]));
253 clusters.push_back(coreNum);
254 clustersMap_.insert(std::pair<uint16_t, uint16_t>(i, coreNum));
255 }
256 }
257
ReadClusterTimeIncrement(std::vector<int64_t> & clusterTime,std::vector<int64_t> & increments,int32_t uid,std::vector<uint16_t> & clusters,std::string & timeLine)258 bool CpuTimeReader::ReadClusterTimeIncrement(std::vector<int64_t>& clusterTime, std::vector<int64_t>& increments,
259 int32_t uid, std::vector<uint16_t>& clusters, std::string& timeLine)
260 {
261 std::vector<std::string> splitedTime;
262 Split(timeLine, ' ', splitedTime);
263 uint16_t count = 0;
264 for (uint16_t i = 0; i < clusters.size(); i++) {
265 int64_t tempTimeMs = 0;
266 for (uint16_t j = 0; j < clusters[i]; j++) {
267 tempTimeMs += stoll(splitedTime[count++]) * 10; // Unit is 10ms
268 }
269 clusterTime.push_back(tempTimeMs);
270 }
271
272 auto iterLast = lastClusterTimeMap_.find(uid);
273 if (iterLast != lastClusterTimeMap_.end()) {
274 for (uint16_t i = 0; i < clusters.size(); i++) {
275 int64_t increment = clusterTime[i] - iterLast->second[i];
276 if (increment >= 0) {
277 iterLast->second[i] = clusterTime[i];
278 increments.push_back(increment);
279 } else {
280 STATS_HILOGD(COMP_SVC, "Negative cpu cluster time increment");
281 return false;
282 }
283 }
284 } else {
285 lastClusterTimeMap_.insert(std::pair<int32_t, std::vector<int64_t>>(uid, clusterTime));
286 increments = clusterTime;
287 STATS_HILOGI(COMP_SVC, "Add last cpu cluster time for uid: %{public}d", uid);
288 }
289 return true;
290 }
291
ReadUidCpuClusterTime()292 bool CpuTimeReader::ReadUidCpuClusterTime()
293 {
294 std::ifstream input(UID_CPU_CLUSTER_TIME_FILE);
295 if (!input) {
296 STATS_HILOGW(COMP_SVC, "Open file failed");
297 return false;
298 }
299 std::string line;
300 int32_t uid = -1;
301 std::vector<uint16_t> clusters;
302 std::vector<int64_t> clusterTime;
303 while (getline(input, line)) {
304 clusterTime.clear();
305 if (line.find("policy") != line.npos) {
306 ReadPolicy(clusters, line);
307 continue;
308 }
309
310 std::vector<std::string> splitedLine;
311 Split(line, ':', splitedLine);
312 uid = stoi(splitedLine[0]);
313 if (uid > StatsUtils::INVALID_VALUE) {
314 auto bss = BatteryStatsService::GetInstance();
315 auto uidEntity = bss->GetBatteryStatsCore()->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
316 if (uidEntity) {
317 uidEntity->UpdateUidMap(uid);
318 }
319 }
320
321 std::vector<int64_t> increments;
322 if (!ReadClusterTimeIncrement(clusterTime, increments, uid, clusters, splitedLine[1])) {
323 return false;
324 }
325
326 if (StatsHelper::IsOnBattery()) {
327 STATS_HILOGD(COMP_SVC, "Power supply is not connected. Add the increment");
328 auto iter = clusterTimeMap_.find(uid);
329 if (iter != clusterTimeMap_.end()) {
330 AddIncrementsToClusterTime(iter->second, increments, clusters);
331 } else {
332 clusterTimeMap_.insert(std::pair<int32_t, std::vector<int64_t>>(uid, increments));
333 STATS_HILOGI(COMP_SVC, "Add cpu cluster time for uid: %{public}d", uid);
334 }
335 }
336 }
337 return true;
338 }
339
AddIncrementsToClusterTime(std::vector<int64_t> & clusterTime,const std::vector<int64_t> & increments,const std::vector<uint16_t> & clusters)340 void CpuTimeReader::AddIncrementsToClusterTime(std::vector<int64_t>& clusterTime,
341 const std::vector<int64_t>& increments, const std::vector<uint16_t>& clusters)
342 {
343 for (uint16_t i = 0; i < clusters.size(); i++) {
344 clusterTime[i] += increments[i];
345 }
346 }
347
ProcessFreqTime(std::map<uint32_t,std::vector<int64_t>> & map,std::map<uint32_t,std::vector<int64_t>> & increments,std::map<uint32_t,std::vector<int64_t>> & speedTime,int32_t index,int32_t uid)348 bool CpuTimeReader::ProcessFreqTime(std::map<uint32_t, std::vector<int64_t>>& map, std::map<uint32_t,
349 std::vector<int64_t>>& increments, std::map<uint32_t, std::vector<int64_t>>& speedTime, int32_t index, int32_t uid)
350 {
351 auto iterLastTemp = map.find(index);
352 if (iterLastTemp != map.end()) {
353 std::vector<int64_t> lastSpeedTimes = iterLastTemp->second;
354 std::vector<int64_t> newIncrementTimes;
355 newIncrementTimes.clear();
356 for (uint16_t j = 0; j < lastSpeedTimes.size(); j++) {
357 int64_t increment = speedTime.at(index)[j] - lastSpeedTimes[j];
358 if (increment >= 0) {
359 newIncrementTimes.push_back(increment);
360 increments.insert(std::pair<uint32_t, std::vector<int64_t>>(index, newIncrementTimes));
361 } else {
362 STATS_HILOGI(COMP_SVC, "Negative cpu freq time increment");
363 return false;
364 }
365 }
366 iterLastTemp->second = speedTime.at(index);
367 }
368 return true;
369 }
370
ReadFreqTimeIncrement(std::map<uint32_t,std::vector<int64_t>> & speedTime,std::map<uint32_t,std::vector<int64_t>> & increments,int32_t uid,std::vector<std::string> & splitedTime)371 bool CpuTimeReader::ReadFreqTimeIncrement(std::map<uint32_t, std::vector<int64_t>>& speedTime,
372 std::map<uint32_t, std::vector<int64_t>>& increments, int32_t uid, std::vector<std::string>& splitedTime)
373 {
374 auto bss = BatteryStatsService::GetInstance();
375 auto parser = bss->GetBatteryStatsParser();
376 uint16_t clusterNum = parser->GetClusterNum();
377 uint16_t count = 0;
378 for (uint16_t i = 0; i < clusterNum; i++) {
379 std::vector<int64_t> tempSpeedTimes;
380 tempSpeedTimes.clear();
381 for (uint16_t j = 0; j < parser->GetSpeedNum(i); j++) {
382 int64_t tempTimeMs = stoll(splitedTime[count++]) * 10; // Unit is 10ms
383 tempSpeedTimes.push_back(tempTimeMs);
384 }
385 speedTime.insert(std::pair<uint32_t, std::vector<int64_t>>(i, tempSpeedTimes));
386 }
387
388 auto iterLast = lastFreqTimeMap_.find(uid);
389 if (iterLast == lastFreqTimeMap_.end()) {
390 lastFreqTimeMap_.insert(std::pair<int32_t, std::map<uint32_t, std::vector<int64_t>>>(uid, speedTime));
391 increments = speedTime;
392 STATS_HILOGI(COMP_SVC, "Add last cpu freq time for uid: %{public}d", uid);
393 return true;
394 }
395 for (uint16_t i = 0; i < lastFreqTimeMap_.size(); i++) {
396 if (!ProcessFreqTime(iterLast->second, increments, speedTime, i, uid)) {
397 return false;
398 }
399 }
400 return true;
401 }
402
DistributeFreqTime(std::map<uint32_t,std::vector<int64_t>> & uidIncrements,std::map<uint32_t,std::vector<int64_t>> & increments)403 void CpuTimeReader::DistributeFreqTime(std::map<uint32_t, std::vector<int64_t>>& uidIncrements,
404 std::map<uint32_t, std::vector<int64_t>>& increments)
405 {
406 auto bss = BatteryStatsService::GetInstance();
407 auto parser = bss->GetBatteryStatsParser();
408 uint16_t clusterNum = parser->GetClusterNum();
409 if (wakelockCounts_ > 0) {
410 for (uint16_t i = 0; i < clusterNum; i++) {
411 uint16_t speedNum = parser->GetSpeedNum(i);
412 for (uint16_t j = 0; j < speedNum; j++) {
413 int32_t step = 2;
414 uidIncrements.at(i)[j] = increments.at(i)[j] / step;
415 }
416 }
417 // TO-DO, distribute half of cpu freq time to wakelock holders
418 }
419 }
420
AddFreqTimeToUid(std::map<uint32_t,std::vector<int64_t>> & uidIncrements,int32_t uid)421 void CpuTimeReader::AddFreqTimeToUid(std::map<uint32_t, std::vector<int64_t>>& uidIncrements, int32_t uid)
422 {
423 auto bss = BatteryStatsService::GetInstance();
424 auto parser = bss->GetBatteryStatsParser();
425 uint16_t clusterNum = parser->GetClusterNum();
426 auto iter = freqTimeMap_.find(uid);
427 if (iter != freqTimeMap_.end()) {
428 for (uint16_t i = 0; i < clusterNum; i++) {
429 uint16_t speedNum = parser->GetSpeedNum(i);
430 for (uint16_t j = 0; j < speedNum; j++) {
431 iter->second.at(i)[j] += uidIncrements.at(i)[j];
432 }
433 }
434 } else {
435 freqTimeMap_.insert(std::pair<int32_t, std::map<uint32_t, std::vector<int64_t>>>(uid, uidIncrements));
436 STATS_HILOGI(COMP_SVC, "Add cpu freq time for uid: %{public}d", uid);
437 }
438 }
439
ReadUidCpuFreqTime()440 bool CpuTimeReader::ReadUidCpuFreqTime()
441 {
442 std::ifstream input(UID_CPU_FREQ_TIME_FILE);
443 if (!input) {
444 STATS_HILOGW(COMP_SVC, "Open file failed");
445 return false;
446 }
447 std::string line;
448 int32_t uid = -1;
449 std::map<uint32_t, std::vector<int64_t>> speedTime;
450 while (getline(input, line)) {
451 speedTime.clear();
452 std::vector<std::string> splitedLine;
453 Split(line, ':', splitedLine);
454 if (splitedLine[0] == "uid") {
455 continue;
456 } else {
457 uid = stoi(splitedLine[0]);
458 }
459
460 if (uid > StatsUtils::INVALID_VALUE) {
461 auto bss = BatteryStatsService::GetInstance();
462 auto uidEntity =
463 bss->GetBatteryStatsCore()->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
464 if (uidEntity) {
465 uidEntity->UpdateUidMap(uid);
466 }
467 }
468
469 std::vector<std::string> splitedTime;
470 Split(splitedLine[1], ' ', splitedTime);
471
472 std::map<uint32_t, std::vector<int64_t>> increments;
473 if (!ReadFreqTimeIncrement(speedTime, increments, uid, splitedTime)) {
474 return false;
475 }
476
477 std::map<uint32_t, std::vector<int64_t>> uidIncrements = increments;
478 DistributeFreqTime(uidIncrements, increments);
479
480 if (!StatsHelper::IsOnBattery()) {
481 STATS_HILOGD(COMP_SVC, "Power supply is connected, don't add the increment");
482 continue;
483 }
484 AddFreqTimeToUid(uidIncrements, uid);
485 }
486 return true;
487 }
488
ReadUidTimeIncrement(std::vector<int64_t> & cpuTime,std::vector<int64_t> & uidIncrements,int32_t uid,std::string & timeLine)489 bool CpuTimeReader::ReadUidTimeIncrement(std::vector<int64_t>& cpuTime, std::vector<int64_t>& uidIncrements,
490 int32_t uid, std::string& timeLine)
491 {
492 std::vector<std::string> splitedTime;
493 Split(timeLine, ' ', splitedTime);
494 for (uint16_t i = 0; i < splitedTime.size(); i++) {
495 int64_t tempTime = 0;
496 tempTime = stoll(splitedTime[i]);
497 cpuTime.push_back(tempTime);
498 }
499
500 std::vector<int64_t> increments;
501 auto iterLast = lastUidTimeMap_.find(uid);
502 if (iterLast != lastUidTimeMap_.end()) {
503 for (uint16_t i = 0; i < splitedTime.size(); i++) {
504 int64_t increment = 0;
505 increment = cpuTime[i] - iterLast->second[i];
506 if (increment >= 0) {
507 iterLast->second[i] = cpuTime[i];
508 increments.push_back(increment);
509 } else {
510 STATS_HILOGI(COMP_SVC, "Negative cpu time increment");
511 return false;
512 }
513 }
514 } else {
515 lastUidTimeMap_.insert(std::pair<int32_t, std::vector<int64_t>>(uid, cpuTime));
516 increments = cpuTime;
517 STATS_HILOGI(COMP_SVC, "Add last cpu time for uid: %{public}d", uid);
518 }
519
520 uidIncrements = increments;
521
522 if (wakelockCounts_ > 0) {
523 double weight = 0.5;
524 uidIncrements[0] = increments[0] / (StatsUtils::US_IN_MS * 1.0) * weight;
525 uidIncrements[1] = increments[1] / (StatsUtils::US_IN_MS * 1.0) * weight;
526 // TO-DO, distribute half of cpu time to wakelock holders
527 }
528 return true;
529 }
530
ReadUidCpuTime()531 bool CpuTimeReader::ReadUidCpuTime()
532 {
533 std::ifstream input(UID_CPU_TIME_FILE);
534 if (!input) {
535 STATS_HILOGW(COMP_SVC, "Open file failed");
536 return false;
537 }
538 std::string line;
539 std::vector<int64_t> cpuTime;
540 while (getline(input, line)) {
541 cpuTime.clear();
542 std::vector<std::string> splitedLine;
543 Split(line, ':', splitedLine);
544 int32_t uid = stoi(splitedLine[0]);
545 if (uid > StatsUtils::INVALID_VALUE) {
546 auto bss = BatteryStatsService::GetInstance();
547 auto uidEntity =
548 bss->GetBatteryStatsCore()->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
549 if (uidEntity) {
550 uidEntity->UpdateUidMap(uid);
551 }
552 }
553
554 std::vector<int64_t> uidIncrements;
555 if (!ReadUidTimeIncrement(cpuTime, uidIncrements, uid, splitedLine[1])) {
556 return false;
557 }
558
559 if (StatsHelper::IsOnBattery()) {
560 STATS_HILOGD(COMP_SVC, "Power supply is not connected. Add the increment");
561 UpdateUidTimeMap(uid, uidIncrements);
562 }
563 }
564 return true;
565 }
566
UpdateUidTimeMap(int32_t uid,const std::vector<int64_t> & uidIncrements)567 void CpuTimeReader::UpdateUidTimeMap(int32_t uid, const std::vector<int64_t>& uidIncrements)
568 {
569 auto iter = uidTimeMap_.find(uid);
570 if (iter != uidTimeMap_.end()) {
571 for (uint16_t i = 0; i < uidIncrements.size(); i++) {
572 iter->second[i] = uidIncrements[i];
573 }
574 } else {
575 uidTimeMap_.insert(std::pair<int32_t, std::vector<int64_t>>(uid, uidIncrements));
576 STATS_HILOGI(COMP_SVC, "Add cpu time for uid: %{public}d", uid);
577 }
578 }
579
Split(std::string & origin,char delimiter,std::vector<std::string> & splited)580 void CpuTimeReader::Split(std::string &origin, char delimiter, std::vector<std::string> &splited)
581 {
582 size_t start;
583 size_t end = 0;
584
585 while ((start = origin.find_first_not_of(delimiter, end)) != std::string::npos) {
586 end = origin.find(delimiter, start);
587 splited.push_back(origin.substr(start, end - start));
588 }
589 }
590 } // namespace PowerMgr
591 } // namespace OHOS