• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sstream>
21 
22 #include <cJSON.h>
23 
24 #include "ios"
25 #include "string_ex.h"
26 
27 #include "stats_cjson_utils.h"
28 #include "stats_utils.h"
29 #include "config_policy_utils.h"
30 
31 namespace OHOS {
32 namespace PowerMgr {
33 namespace {
34 static const std::string POWER_AVERAGE_FILE = "etc/power_config/power_average.json";
35 static const std::string VENDOR_POWER_AVERAGE_FILE = "/vendor/etc/power_config/power_average.json";
36 static const std::string SYSTEM_POWER_AVERAGE_FILE = "/system/etc/power_config/power_average.json";
37 } // namespace
Init()38 bool BatteryStatsParser::Init()
39 {
40     char buf[MAX_PATH_LEN];
41     char* path = GetOneCfgFile(POWER_AVERAGE_FILE.c_str(), buf, MAX_PATH_LEN);
42     if (path != nullptr && *path != '\0') {
43         if (LoadAveragePowerFromFile(path)) {
44             return true;
45         }
46         return false;
47     }
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     std::ifstream ifs(path, std::ios::binary);
74     if (!ifs.is_open()) {
75         STATS_HILOGE(COMP_SVC, "Json file doesn't exist");
76         return false;
77     }
78     std::stringstream buffer;
79     buffer << ifs.rdbuf();
80     std::string jsonStr = buffer.str();
81     ifs.close();
82 
83     cJSON* root = cJSON_Parse(jsonStr.c_str());
84     if (!root) {
85         STATS_HILOGE(COMP_SVC, "Failed to parse the JSON file");
86         return false;
87     }
88     if (!StatsJsonUtils::IsValidJsonObjectOrJsonArray(root)) {
89         STATS_HILOGE(COMP_SVC, "root invalid[%{public}s]", path.c_str());
90         cJSON_Delete(root);
91         return false;
92     }
93     cJSON* currentElement = nullptr;
94     cJSON_ArrayForEach(currentElement, root) {
95         const char* type = currentElement->string;
96         if (type == nullptr) {
97             STATS_HILOGE(COMP_SVC, "Invalid key.");
98             continue;
99         }
100         std::string keyStr(type);
101         if (keyStr == StatsUtils::CURRENT_CPU_CLUSTER && StatsJsonUtils::IsValidJsonArray(currentElement)) {
102             clusterNum_ = static_cast<uint16_t>(cJSON_GetArraySize(currentElement));
103             STATS_HILOGD(COMP_SVC, "Read cluster num: %{public}d", clusterNum_);
104         }
105         if (keyStr.find(StatsUtils::CURRENT_CPU_SPEED) != std::string::npos &&
106             StatsJsonUtils::IsValidJsonArray(currentElement)) {
107             STATS_HILOGD(COMP_SVC, "Read speed num: %{public}d",
108                 static_cast<int32_t>(cJSON_GetArraySize(currentElement)));
109             speedNum_.push_back(static_cast<uint16_t>(cJSON_GetArraySize(currentElement)));
110         }
111         if (cJSON_IsArray(currentElement)) {
112             ParsingArray(keyStr, currentElement);
113         } else if (cJSON_IsNumber(currentElement)) {
114             averageMap_.insert(std::pair<std::string, double>(keyStr, currentElement->valuedouble));
115         }
116     }
117     cJSON_Delete(root);
118     return true;
119 }
120 
ParsingArray(const std::string & type,const cJSON * array)121 void BatteryStatsParser::ParsingArray(const std::string& type, const cJSON* array)
122 {
123     std::vector<double> listValues;
124 
125     int size = cJSON_GetArraySize(array);
126     for (int i = 0; i < size; i++) {
127         cJSON* item = cJSON_GetArrayItem(array, i);
128         if (StatsJsonUtils::IsValidJsonNumber(item)) {
129             listValues.push_back(item->valuedouble);
130         }
131     }
132 
133     averageVecMap_.insert(std::pair<std::string, std::vector<double>>(type, listValues));
134 }
135 
GetAveragePowerMa(std::string type)136 double BatteryStatsParser::GetAveragePowerMa(std::string type)
137 {
138     double average = 0.0;
139     auto iter = averageMap_.find(type);
140     if (iter != averageMap_.end()) {
141         average = iter->second;
142     }
143     STATS_HILOGD(COMP_SVC, "Get average power: %{public}lfma of %{public}s", average, type.c_str());
144     return average;
145 }
146 
GetAveragePowerMa(std::string type,uint16_t level)147 double BatteryStatsParser::GetAveragePowerMa(std::string type, uint16_t level)
148 {
149     double average = 0.0;
150     auto iter = averageVecMap_.find(type);
151     if (iter != averageVecMap_.end()) {
152         if (level < iter->second.size()) {
153             average = iter->second[level];
154         }
155     }
156     STATS_HILOGD(COMP_SVC, "Get average power: %{public}lf of %{public}s, level: %{public}d",
157         average, type.c_str(), level);
158     return average;
159 }
160 
GetClusterNum()161 uint16_t BatteryStatsParser::GetClusterNum()
162 {
163     return clusterNum_;
164 }
165 
DumpInfo(std::string & result)166 void BatteryStatsParser::DumpInfo(std::string& result)
167 {
168     result.append("POWER AVERAGE CONFIGATION DUMP:\n");
169     result.append("\n");
170     for (auto iter : averageMap_) {
171         result.append(iter.first).append(" : ").append(ToString(iter.second)).append("\n");
172     }
173     for (auto vecIter : averageVecMap_) {
174         result.append(vecIter.first).append(" : [");
175         for (auto levelIter : vecIter.second) {
176             result.append(" ").append(ToString(levelIter));
177         }
178         result.append(" ]").append("\n");
179     }
180 }
181 } // namespace PowerMgr
182 } // namespace OHOS
183