1 /*
2 * Copyright (c) 2021-2023 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 "battery_stats_parser.h"
17
18 #include <algorithm>
19 #include <fstream>
20 #include "ios"
21 #include "json/reader.h"
22 #include "string_ex.h"
23
24 #include "stats_utils.h"
25 #include "config_policy_utils.h"
26
27 namespace OHOS {
28 namespace PowerMgr {
29 namespace {
30 static const std::string POWER_AVERAGE_FILE = "etc/profile/power_average.json";
31 static const std::string VENDOR_POWER_AVERAGE_FILE = "/vendor/etc/profile/power_average.json";
32 static const std::string SYSTEM_POWER_AVERAGE_FILE = "/system/etc/profile/power_average.json";
33 } // namespace
Init()34 bool BatteryStatsParser::Init()
35 {
36 char buf[MAX_PATH_LEN];
37 char* path = GetOneCfgFile(POWER_AVERAGE_FILE.c_str(), buf, MAX_PATH_LEN);
38 if (path != nullptr && *path != '\0') {
39 if (LoadAveragePowerFromFile(path)) {
40 return true;
41 }
42 return false;
43 }
44 if (!LoadAveragePowerFromFile(VENDOR_POWER_AVERAGE_FILE)) {
45 STATS_HILOGE(COMP_SVC, "Failed to load vendor average power file");
46 if (!LoadAveragePowerFromFile(SYSTEM_POWER_AVERAGE_FILE)) {
47 STATS_HILOGE(COMP_SVC, "Failed to load system average power file");
48 return false;
49 }
50 }
51 return true;
52 }
53
GetSpeedNum(uint16_t cluster)54 uint16_t BatteryStatsParser::GetSpeedNum(uint16_t cluster)
55 {
56 for (uint16_t i = 0; i < speedNum_.size(); i++) {
57 if (cluster == i) {
58 STATS_HILOGD(COMP_SVC, "Get speed num: %{public}d, for cluster: %{public}d", speedNum_[i],
59 cluster);
60 return speedNum_[i];
61 }
62 }
63 STATS_HILOGW(COMP_SVC, "No related speed number, return 0");
64 return StatsUtils::DEFAULT_VALUE;
65 }
66
LoadAveragePowerFromFile(const std::string & path)67 bool BatteryStatsParser::LoadAveragePowerFromFile(const std::string& path)
68 {
69 Json::CharReaderBuilder reader;
70 Json::Value root;
71 std::string errors;
72 std::ifstream ifs(path, std::ios::binary);
73 if (!ifs.is_open()) {
74 STATS_HILOGE(COMP_SVC, "Json file doesn't exist");
75 return false;
76 }
77 if (!parseFromStream(reader, ifs, &root, &errors)) {
78 STATS_HILOGE(COMP_SVC, "Failed to parse the JSON file");
79 ifs.close();
80 return false;
81 }
82 ifs.close();
83
84 Json::Value::Members members = root.getMemberNames();
85 for (auto iter = members.begin(); iter != members.end(); iter++) {
86 std::string type = *iter;
87 Json::Value value = root[type];
88
89 if (type == StatsUtils::CURRENT_CPU_CLUSTER) {
90 clusterNum_ = value.size();
91 STATS_HILOGD(COMP_SVC, "Read cluster num: %{public}d", clusterNum_);
92 }
93
94 if (type.find(StatsUtils::CURRENT_CPU_SPEED) != std::string::npos) {
95 STATS_HILOGD(COMP_SVC, "Read speed num: %{public}d", static_cast<int32_t>(value.size()));
96 speedNum_.push_back(value.size());
97 }
98
99 if (value.isArray()) {
100 ParsingArray(type, value);
101 } else if (value.isDouble()) {
102 averageMap_.insert(std::pair<std::string, double>(type, value.asDouble()));
103 }
104 }
105 return true;
106 }
107
ParsingArray(const std::string & type,const Json::Value & array)108 void BatteryStatsParser::ParsingArray(const std::string& type, const Json::Value& array)
109 {
110 std::vector<double> listValues;
111 std::for_each(array.begin(), array.end(), [&](const Json::Value& value) {
112 if (value.isDouble()) {
113 listValues.push_back(value.asDouble());
114 }
115 });
116 averageVecMap_.insert(std::pair<std::string, std::vector<double>>(type, listValues));
117 }
118
GetAveragePowerMa(std::string type)119 double BatteryStatsParser::GetAveragePowerMa(std::string type)
120 {
121 double average = 0.0;
122 auto iter = averageMap_.find(type);
123 if (iter != averageMap_.end()) {
124 average = iter->second;
125 }
126 STATS_HILOGD(COMP_SVC, "Get average power: %{public}lfma of %{public}s", average, type.c_str());
127 return average;
128 }
129
GetAveragePowerMa(std::string type,uint16_t level)130 double BatteryStatsParser::GetAveragePowerMa(std::string type, uint16_t level)
131 {
132 double average = 0.0;
133 auto iter = averageVecMap_.find(type);
134 if (iter != averageVecMap_.end()) {
135 if (level < iter->second.size()) {
136 average = iter->second[level];
137 }
138 }
139 STATS_HILOGD(COMP_SVC, "Get average power: %{public}lf of %{public}s, level: %{public}d",
140 average, type.c_str(), level);
141 return average;
142 }
143
GetClusterNum()144 uint16_t BatteryStatsParser::GetClusterNum()
145 {
146 return clusterNum_;
147 }
148
DumpInfo(std::string & result)149 void BatteryStatsParser::DumpInfo(std::string& result)
150 {
151 result.append("POWER AVERAGE CONFIGATION DUMP:\n");
152 result.append("\n");
153 for (auto iter : averageMap_) {
154 result.append(iter.first).append(" : ").append(ToString(iter.second)).append("\n");
155 }
156 for (auto vecIter : averageVecMap_) {
157 result.append(vecIter.first).append(" : [");
158 for (auto levelIter : vecIter.second) {
159 result.append(" ").append(ToString(levelIter));
160 }
161 result.append(" ]").append("\n");
162 }
163 }
164 } // namespace PowerMgr
165 } // namespace OHOS
166