• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_config.h"
17 
18 #include "battery_log.h"
19 
20 #include "string_ex.h"
21 #include "config_policy_utils.h"
22 
23 namespace OHOS {
24 namespace HDI {
25 namespace Battery {
26 namespace V2_0 {
27 namespace {
28 constexpr const char* BATTERY_CONFIG_PATH = "etc/battery/battery_config.json";
29 constexpr const char* SYSTEM_BATTERY_CONFIG_PATH = "/system/etc/battery/battery_config.json";
30 constexpr const char* VENDOR_BATTERY_CONFIG_PATH = "/vendor/etc/battery/battery_config.json";
31 constexpr const char* BATTERY_CONFIG_EXCEPTION_PATH = "";
32 constexpr int32_t MAP_KEY_INDEX = 0;
33 constexpr int32_t BEGIN_SOC_INDEX = 0;
34 constexpr int32_t END_SOC_INDEX = 1;
35 constexpr int32_t MAX_SOC_RANGE = 2;
36 constexpr int32_t RED_INDEX = 0;
37 constexpr int32_t GREEN_INDEX = 1;
38 constexpr int32_t BLUE_INDEX = 2;
39 constexpr int32_t MAX_RGB_RANGE = 3;
40 constexpr int32_t MAX_DEPTH = 5;
41 constexpr int32_t MIN_DEPTH = 1;
42 constexpr uint32_t MOVE_LEFT_16 = 16;
43 constexpr uint32_t MOVE_LEFT_8 = 8;
44 }
45 std::shared_ptr<BatteryConfig> BatteryConfig::instance_ = nullptr;
46 std::mutex BatteryConfig::mutex_;
47 
GetInstance()48 BatteryConfig& BatteryConfig::GetInstance()
49 {
50     std::lock_guard<std::mutex> lock(mutex_);
51     if (instance_ == nullptr) {
52         instance_ = std::make_shared<BatteryConfig>();
53     }
54     return *(instance_.get());
55 }
56 
ParseConfig()57 bool BatteryConfig::ParseConfig()
58 {
59     char buf[MAX_PATH_LEN];
60     char* path = GetOneCfgFile(BATTERY_CONFIG_PATH, buf, MAX_PATH_LEN);
61     if (path == nullptr || *path == '\0') {
62         BATTERY_HILOGW(COMP_HDI, "GetOneCfgFile battery_config.json is NULL");
63         path = const_cast<char*>(BATTERY_CONFIG_EXCEPTION_PATH);
64     }
65     BATTERY_HILOGD(COMP_HDI, "GetOneCfgFile battery_config.json");
66 
67     Json::CharReaderBuilder readerBuilder;
68     std::ifstream ifsConf;
69 
70     if (!OpenFile(ifsConf, path)) {
71         return false;
72     }
73 
74     Json::Value config;
75     readerBuilder["collectComments"] = false;
76     JSONCPP_STRING errs;
77 
78     if (parseFromStream(readerBuilder, ifsConf, &config, &errs) && !config.empty()) {
79         ParseConfInner(config);
80     }
81     ifsConf.close();
82     return true;
83 }
84 
GetLightConfig() const85 const std::vector<BatteryConfig::LightConfig>& BatteryConfig::GetLightConfig() const
86 {
87     return lightConfig_;
88 }
89 
GetChargerConfig() const90 const BatteryConfig::ChargerConfig& BatteryConfig::GetChargerConfig() const
91 {
92     return chargerConfig_;
93 }
94 
GetChargeSceneConfigMap() const95 const std::map<std::string, BatteryConfig::ChargeSceneConfig>& BatteryConfig::GetChargeSceneConfigMap() const
96 {
97     return chargeSceneConfigMap_;
98 }
99 
GetUeventList() const100 const std::map<std::string, std::vector<std::string>>& BatteryConfig::GetUeventList() const
101 {
102     return ueventMap_;
103 }
104 
DestroyInstance()105 void BatteryConfig::DestroyInstance()
106 {
107     std::lock_guard<std::mutex> lock(mutex_);
108     instance_ = nullptr;
109 }
110 
OpenFile(std::ifstream & ifsConf,const std::string & configPath)111 bool BatteryConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath)
112 {
113     bool isOpen = false;
114     if (!configPath.empty()) {
115         ifsConf.open(configPath);
116         isOpen = ifsConf.is_open();
117         BATTERY_HILOGD(COMP_HDI, "open file is %{public}d", isOpen);
118     }
119     if (isOpen) {
120         return true;
121     }
122 
123     ifsConf.open(VENDOR_BATTERY_CONFIG_PATH);
124     isOpen = ifsConf.is_open();
125     BATTERY_HILOGI(COMP_HDI, "open then vendor battery_config.json is %{public}d", isOpen);
126 
127     if (isOpen) {
128         return true;
129     }
130 
131     ifsConf.open(SYSTEM_BATTERY_CONFIG_PATH);
132     isOpen = ifsConf.is_open();
133     BATTERY_HILOGI(FEATURE_CHARGING, "open then system battery_config.json is %{public}d", isOpen);
134     return isOpen;
135 }
136 
ParseConfInner(const Json::Value & config)137 void BatteryConfig::ParseConfInner(const Json::Value& config)
138 {
139     BATTERY_HILOGI(COMP_HDI, "start parse battery config inner");
140     ParseLightConfig(GetValue(config, "light"));
141     ParseChargerConfig(GetValue(config, "charger"));
142     ParseChargeSceneConfig(GetValue(config, "charge_scene"));
143     ParseUeventConfig(GetValue(config, "uevent"));
144 }
145 
ParseChargerConfig(const Json::Value & chargerConfig)146 void BatteryConfig::ParseChargerConfig(const Json::Value& chargerConfig)
147 {
148     if (chargerConfig.isNull() || !chargerConfig.isObject()) {
149         BATTERY_HILOGW(COMP_HDI, "chargerConfig is invalid");
150         return;
151     }
152 
153     Json::Value currentPath = GetValue(chargerConfig, "current_limit.path");
154     if (isValidJsonString(currentPath)) {
155         chargerConfig_.currentPath = currentPath.asString();
156     }
157 
158     Json::Value voltagePath = GetValue(chargerConfig, "voltage_limit.path");
159     if (isValidJsonString(voltagePath)) {
160         chargerConfig_.voltagePath = voltagePath.asString();
161     }
162 
163     Json::Value chargeTypePath = GetValue(chargerConfig, "type.path");
164     if (isValidJsonString(chargeTypePath)) {
165         chargerConfig_.chargeTypePath = chargeTypePath.asString();
166     }
167     BATTERY_HILOGI(COMP_HDI, "The battery charger configuration parse succeed");
168 }
169 
ParseLightConfig(const Json::Value & lightConfig)170 void BatteryConfig::ParseLightConfig(const Json::Value& lightConfig)
171 {
172     if (lightConfig.isNull() || !lightConfig.isObject()) {
173         BATTERY_HILOGW(COMP_HDI, "lightConf is invalid");
174         return;
175     }
176     lightConfig_.clear();
177     Json::Value::Members members = lightConfig.getMemberNames();
178     for (auto iter = members.begin(); iter != members.end(); iter++) {
179         std::string key = *iter;
180         Json::Value valueObj = lightConfig[key];
181         if (valueObj.isNull() || !valueObj.isObject()) {
182             BATTERY_HILOGW(COMP_HDI, "The light conf is invalid, key=%{public}s", key.c_str());
183             continue;
184         }
185 
186         Json::Value soc = GetValue(valueObj, "soc");
187         Json::Value rgb = GetValue(valueObj, "rgb");
188         if (!soc.isArray() || !rgb.isArray()) {
189             BATTERY_HILOGW(COMP_HDI, "The battery light %{public}s configuration is invalid.", key.c_str());
190             continue;
191         }
192         if (soc.size() != MAX_SOC_RANGE || !soc[BEGIN_SOC_INDEX].isInt() || !soc[END_SOC_INDEX].isInt()) {
193             BATTERY_HILOGW(COMP_HDI, "The battery light %{public}s soc data type error.", key.c_str());
194             continue;
195         }
196         if (rgb.size() != MAX_RGB_RANGE || !rgb[RED_INDEX].isUInt() || !rgb[GREEN_INDEX].isUInt() ||
197             !rgb[BLUE_INDEX].isUInt()) {
198             BATTERY_HILOGW(COMP_HDI, "The battery light %{public}s rgb data type error.", key.c_str());
199             continue;
200         }
201 
202         BatteryConfig::LightConfig tempLightConfig = {
203             .beginSoc = soc[BEGIN_SOC_INDEX].asInt(),
204             .endSoc = soc[END_SOC_INDEX].asInt(),
205             .rgb = (rgb[RED_INDEX].asUInt() << MOVE_LEFT_16) |
206                 (rgb[GREEN_INDEX].asUInt() << MOVE_LEFT_8) |
207                 rgb[BLUE_INDEX].asUInt()
208         };
209         lightConfig_.push_back(tempLightConfig);
210     }
211     BATTERY_HILOGI(COMP_HDI, "The battery light configuration size %{public}d",
212         static_cast<int32_t>(lightConfig_.size()));
213 }
214 
ParseChargeSceneConfig(const Json::Value & chargeSceneConfig)215 void BatteryConfig::ParseChargeSceneConfig(const Json::Value& chargeSceneConfig)
216 {
217     if (chargeSceneConfig.isNull() || !chargeSceneConfig.isObject()) {
218         BATTERY_HILOGW(COMP_HDI, "chargeSceneConfig is invalid");
219         return;
220     }
221 
222     chargeSceneConfigMap_.clear();
223     Json::Value::Members members = chargeSceneConfig.getMemberNames();
224     for (auto iter = members.begin(); iter != members.end(); iter++) {
225         std::string key = *iter;
226         Json::Value valueObj = chargeSceneConfig[key];
227         if (key.empty() || valueObj.isNull() || !valueObj.isObject()) {
228             BATTERY_HILOGW(COMP_HDI, "The charge scene config is invalid, key=%{public}s", key.c_str());
229             continue;
230         }
231 
232         Json::Value supportPath = GetValue(valueObj, "support.path");
233         Json::Value type = GetValue(valueObj, "support.type");
234         Json::Value expectValue = GetValue(valueObj, "support.expect_value");
235         Json::Value setPath = GetValue(valueObj, "set.path");
236         Json::Value getPath = GetValue(valueObj, "get.path");
237         if (!isValidJsonString(supportPath) && !isValidJsonString(setPath) && !isValidJsonString(getPath)) {
238             BATTERY_HILOGW(COMP_HDI, "The charge scene config path is invalid, key=%{public}s", key.c_str());
239             continue;
240         }
241 
242         BatteryConfig::ChargeSceneConfig tempChargeSceneConfig;
243         if (isValidJsonString(supportPath)) {
244             tempChargeSceneConfig.supportPath = supportPath.asString();
245             tempChargeSceneConfig.type = isValidJsonString(type) ? type.asString() : "";
246             tempChargeSceneConfig.expectValue = isValidJsonString(expectValue) ? expectValue.asString() : "";
247         }
248 
249         if (isValidJsonString(setPath)) {
250             tempChargeSceneConfig.setPath = setPath.asString();
251         }
252 
253         if (isValidJsonString(getPath)) {
254             tempChargeSceneConfig.getPath = getPath.asString();
255         }
256         chargeSceneConfigMap_.insert(std::make_pair(key, tempChargeSceneConfig));
257     }
258     BATTERY_HILOGI(COMP_HDI, "The charge scene config size: %{public}d",
259         static_cast<int32_t>(chargeSceneConfigMap_.size()));
260 }
261 
ParseUeventConfig(const Json::Value & ueventConfig)262 void BatteryConfig::ParseUeventConfig(const Json::Value& ueventConfig)
263 {
264     if (ueventConfig.isNull() || !ueventConfig.isObject()) {
265         BATTERY_HILOGW(COMP_HDI, "ueventConfig is invalid");
266         return;
267     }
268     ueventMap_.clear();
269     Json::Value::Members members = ueventConfig.getMemberNames();
270     for (auto iter = members.begin(); iter != members.end(); iter++) {
271         std::string key = *iter;
272         Json::Value valueObj = ueventConfig[key];
273         if (valueObj.isNull() || !valueObj.isObject()) {
274             BATTERY_HILOGW(COMP_HDI, "The uevent conf is invalid, key=%{public}s", key.c_str());
275             continue;
276         }
277         std::vector<std::string> ueventList;
278         Json::Value::Members ObjMembers = valueObj.getMemberNames();
279         for (auto it = ObjMembers.begin(); it != ObjMembers.end(); it++) {
280             ueventList.push_back(*it);
281         }
282         ueventMap_.emplace(*iter, ueventList);
283         BATTERY_HILOGI(COMP_HDI, "%{public}s size: %{public}d", key.c_str(),
284             static_cast<int32_t>(ueventList.size()));
285     }
286     BATTERY_HILOGI(COMP_HDI, "The uevent config size: %{public}d", static_cast<int32_t>(ueventMap_.size()));
287 }
288 
SplitKey(const std::string & key,std::vector<std::string> & keys) const289 bool BatteryConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const
290 {
291     SplitStr(TrimStr(key), ".", keys);
292     return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true;
293 }
294 
GetValue(const Json::Value & config,std::string key) const295 Json::Value BatteryConfig::GetValue(const Json::Value& config, std::string key) const
296 {
297     std::vector<std::string> keys;
298     if (!SplitKey(key, keys)) {
299         BATTERY_HILOGW(COMP_HDI, "The key does not meet the. key=%{public}s", key.c_str());
300         return Json::Value();
301     }
302 
303     std::string firstKey = keys[MAP_KEY_INDEX];
304     Json::Value value = (config.isObject() && config.isMember(firstKey)) ? config[firstKey] : Json::Value();
305     if (value.isNull()) {
306         BATTERY_HILOGW(COMP_HDI, "Value is empty. key=%{public}s", keys[MAP_KEY_INDEX].c_str());
307         return value;
308     }
309 
310     for (size_t i = 1; i < keys.size(); ++i) {
311         if (!value.isObject() || !value.isMember(keys[i])) {
312             BATTERY_HILOGW(COMP_HDI, "The key is not configured. key=%{public}s", keys[i].c_str());
313             break;
314         }
315         value = value[keys[i]];
316     }
317     return value;
318 }
319 
isValidJsonString(const Json::Value & config) const320 bool BatteryConfig::isValidJsonString(const Json::Value& config) const
321 {
322     return !config.isNull() && config.isString();
323 }
324 }  // namespace V2_0
325 }  // namespace Battery
326 }  // namespace HDI
327 }  // namespace OHOS
328