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