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 "string_ex.h"
19 #include "config_policy_utils.h"
20 #include "charger_log.h"
21
22 namespace OHOS {
23 namespace PowerMgr {
24 namespace {
25 constexpr const char* BATTERY_CONFIG_PATH = "etc/battery/battery_config.json";
26 constexpr const char* SYSTEM_BATTERY_CONFIG_PATH = "/system/etc/battery/battery_config.json";
27 constexpr const char* VENDOR_BATTERY_CONFIG_PATH = "/vendor/etc/battery/battery_config.json";
28 constexpr const char* BATTERY_CONFIG_EXCEPTION_PATH = "";
29 constexpr int32_t MAP_KEY_INDEX = 0;
30 constexpr int32_t BEGIN_SOC_INDEX = 0;
31 constexpr int32_t END_SOC_INDEX = 1;
32 constexpr int32_t MAX_SOC_RANGE = 2;
33 constexpr int32_t RED_INDEX = 0;
34 constexpr int32_t GREEN_INDEX = 1;
35 constexpr int32_t BLUE_INDEX = 2;
36 constexpr int32_t MAX_RGB_RANGE = 3;
37 constexpr int32_t MAX_DEPTH = 5;
38 constexpr int32_t MIN_DEPTH = 1;
39 constexpr uint32_t MOVE_LEFT_16 = 16;
40 constexpr uint32_t MOVE_LEFT_8 = 8;
41 } // namespace
42 std::shared_ptr<BatteryConfig> BatteryConfig::instance_ = nullptr;
43 std::mutex BatteryConfig::mutex_;
44
GetInstance()45 BatteryConfig& BatteryConfig::GetInstance()
46 {
47 std::lock_guard<std::mutex> lock(mutex_);
48 if (instance_ == nullptr) {
49 instance_ = std::make_shared<BatteryConfig>();
50 }
51 return *(instance_.get());
52 }
53
ParseConfig()54 bool BatteryConfig::ParseConfig()
55 {
56 char buf[MAX_PATH_LEN];
57 char* path = GetOneCfgFile(BATTERY_CONFIG_PATH, buf, MAX_PATH_LEN);
58 if (path == nullptr || *path == '\0') {
59 BATTERY_HILOGW(FEATURE_CHARGING, "GetOneCfgFile battery_config.json is NULL");
60 path = const_cast<char*>(BATTERY_CONFIG_EXCEPTION_PATH);
61 }
62 BATTERY_HILOGD(FEATURE_CHARGING, "GetOneCfgFile battery_config.json");
63
64 Json::CharReaderBuilder readerBuilder;
65 std::ifstream ifsConf;
66 if (!OpenFile(ifsConf, path)) {
67 return false;
68 }
69
70 config_.clear();
71 readerBuilder["collectComments"] = false;
72 JSONCPP_STRING errs;
73
74 if (parseFromStream(readerBuilder, ifsConf, &config_, &errs) && !config_.empty()) {
75 ParseConfInner();
76 }
77 ifsConf.close();
78 return true;
79 }
80
IsExist(std::string key) const81 bool BatteryConfig::IsExist(std::string key) const
82 {
83 return !GetValue(key).isNull();
84 }
85
GetInt(std::string key,int32_t defVal) const86 int32_t BatteryConfig::GetInt(std::string key, int32_t defVal) const
87 {
88 Json::Value value = GetValue(key);
89 return (value.isNull() || !value.isInt()) ? defVal : value.asInt();
90 }
91
GetString(std::string key,std::string defVal) const92 std::string BatteryConfig::GetString(std::string key, std::string defVal) const
93 {
94 Json::Value value = GetValue(key);
95 return (value.isNull() || !value.isString()) ? defVal : value.asString();
96 }
97
GetLightConf() const98 const std::vector<BatteryConfig::LightConf>& BatteryConfig::GetLightConf() const
99 {
100 return lightConf_;
101 }
102
DestroyInstance()103 void BatteryConfig::DestroyInstance()
104 {
105 std::lock_guard<std::mutex> lock(mutex_);
106 instance_ = nullptr;
107 }
108
OpenFile(std::ifstream & ifsConf,const std::string & configPath)109 bool BatteryConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath)
110 {
111 bool isOpen = false;
112 if (!configPath.empty()) {
113 ifsConf.open(configPath);
114 isOpen = ifsConf.is_open();
115 BATTERY_HILOGD(FEATURE_CHARGING, "open configPath file is %{public}d", isOpen);
116 }
117 if (isOpen) {
118 return true;
119 }
120
121 ifsConf.open(VENDOR_BATTERY_CONFIG_PATH);
122 isOpen = ifsConf.is_open();
123 BATTERY_HILOGI(FEATURE_CHARGING, "open then vendor battery_config.json is %{public}d", isOpen);
124
125 if (isOpen) {
126 return true;
127 }
128
129 ifsConf.open(SYSTEM_BATTERY_CONFIG_PATH);
130 isOpen = ifsConf.is_open();
131 BATTERY_HILOGI(FEATURE_CHARGING, "open then system battery_config.json is %{public}d", isOpen);
132 return isOpen;
133 }
134
ParseConfInner()135 void BatteryConfig::ParseConfInner()
136 {
137 lightConf_.clear();
138 ParseLightConf("low");
139 ParseLightConf("normal");
140 ParseLightConf("high");
141 BATTERY_HILOGD(FEATURE_CHARGING, "The battery light configuration size %{public}d",
142 static_cast<int32_t>(lightConf_.size()));
143 }
144
ParseLightConf(std::string level)145 void BatteryConfig::ParseLightConf(std::string level)
146 {
147 Json::Value soc = GetValue("light." + level + ".soc");
148 Json::Value rgb = GetValue("light." + level + ".rgb");
149 if (!soc.isArray() || !rgb.isArray()) {
150 BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s configuration is invalid.", level.c_str());
151 return;
152 }
153
154 if (soc.size() != MAX_SOC_RANGE || !soc[BEGIN_SOC_INDEX].isInt() || !soc[END_SOC_INDEX].isInt()) {
155 BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s soc data type error.", level.c_str());
156 return;
157 }
158 if (rgb.size() != MAX_RGB_RANGE || !rgb[RED_INDEX].isUInt() || !rgb[GREEN_INDEX].isUInt() ||
159 !rgb[BLUE_INDEX].isUInt()) {
160 BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s rgb data type error.", level.c_str());
161 return;
162 }
163 BatteryConfig::LightConf lightConf = {
164 .beginSoc = soc[BEGIN_SOC_INDEX].asInt(),
165 .endSoc = soc[END_SOC_INDEX].asInt(),
166 .rgb = (rgb[RED_INDEX].asUInt() << MOVE_LEFT_16) |
167 (rgb[GREEN_INDEX].asUInt() << MOVE_LEFT_8) |
168 rgb[BLUE_INDEX].asUInt()
169 };
170 lightConf_.push_back(lightConf);
171 }
172
FindConf(const std::string & key) const173 Json::Value BatteryConfig::FindConf(const std::string& key) const
174 {
175 return (config_.isObject() && config_.isMember(key)) ? config_[key] : Json::Value();
176 }
177
SplitKey(const std::string & key,std::vector<std::string> & keys) const178 bool BatteryConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const
179 {
180 SplitStr(TrimStr(key), ".", keys);
181 return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true;
182 }
183
GetValue(std::string key) const184 Json::Value BatteryConfig::GetValue(std::string key) const
185 {
186 std::vector<std::string> keys;
187 if (!SplitKey(key, keys)) {
188 BATTERY_HILOGW(FEATURE_CHARGING, "The key does not meet the. key=%{public}s", key.c_str());
189 return Json::Value();
190 }
191
192 Json::Value value = FindConf(keys[MAP_KEY_INDEX]);
193 if (value.isNull()) {
194 BATTERY_HILOGD(FEATURE_CHARGING, "Value is empty. key=%{public}s", key.c_str());
195 return value;
196 }
197
198 for (size_t i = 1; i < keys.size(); ++i) {
199 if (!value.isObject() || !value.isMember(keys[i])) {
200 BATTERY_HILOGW(FEATURE_CHARGING, "The key is not configured. key=%{public}s", keys[i].c_str());
201 break;
202 }
203 value = value[keys[i]];
204 }
205 return value;
206 }
207 } // namespace PowerMgr
208 } // namespace OHOS
209