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