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