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 "power_config.h" 17#include "string_ex.h" 18#include "config_policy_utils.h" 19#include "power_hdf_log.h" 20 21namespace OHOS { 22namespace HDI { 23namespace Power { 24namespace V1_2 { 25namespace { 26constexpr const char* POWER_CONFIG_PATH = "etc/power_config/power_config.json"; 27constexpr const char* SYSTEM_POWER_CONFIG_PATH = "/system/etc/power_config/power_config.json"; 28constexpr const char* VENDOR_POWER_CONFIG_PATH = "/vendor/etc/power_config/power_config.json"; 29constexpr const char* POWER_CONFIG_EXCEPTION_PATH = ""; 30constexpr int32_t MAP_KEY_INDEX = 0; 31constexpr int32_t MAX_DEPTH = 5; 32constexpr int32_t MIN_DEPTH = 1; 33} 34 35std::shared_ptr<PowerConfig> PowerConfig::instance_ = nullptr; 36std::mutex PowerConfig::mutex_; 37 38PowerConfig& PowerConfig::GetInstance() 39{ 40 std::lock_guard<std::mutex> lock(mutex_); 41 if (instance_ == nullptr) { 42 instance_ = std::make_shared<PowerConfig>(); 43 } 44 return *(instance_.get()); 45} 46 47void PowerConfig::DestroyInstance() 48{ 49 std::lock_guard<std::mutex> lock(mutex_); 50 instance_ = nullptr; 51} 52 53const std::map<std::string, PowerConfig::PowerSceneConfig>& PowerConfig::GetPowerSceneConfigMap() const 54{ 55 return sceneConfigMap_; 56} 57 58bool PowerConfig::ParseConfig() 59{ 60 char buf[MAX_PATH_LEN]; 61 char* path = GetOneCfgFile(POWER_CONFIG_PATH, buf, MAX_PATH_LEN); 62 if (path == nullptr || *path == '\0') { 63 HDF_LOGW("GetOneCfgFile power_config.json is NULL"); 64 path = const_cast<char*>(POWER_CONFIG_EXCEPTION_PATH); 65 } 66 HDF_LOGI("GetOneCfgFile power_config.json"); 67 68 Json::CharReaderBuilder readerBuilder; 69 std::ifstream ifsConf; 70 71 if (!OpenFile(ifsConf, path)) { 72 return false; 73 } 74 75 Json::Value config; 76 readerBuilder["collectComments"] = false; 77 JSONCPP_STRING errs; 78 79 if (parseFromStream(readerBuilder, ifsConf, &config, &errs) && !config.empty()) { 80 ParseConfInner(config); 81 } 82 ifsConf.close(); 83 return true; 84} 85 86bool PowerConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath) 87{ 88 bool isOpen = false; 89 if (!configPath.empty()) { 90 ifsConf.open(configPath); 91 isOpen = ifsConf.is_open(); 92 HDF_LOGI("path is %{public}s", configPath.c_str()); 93 HDF_LOGI("open file is %{public}d", isOpen); 94 } 95 if (isOpen) { 96 return true; 97 } 98 99 ifsConf.open(VENDOR_POWER_CONFIG_PATH); 100 isOpen = ifsConf.is_open(); 101 HDF_LOGI("open then vendor battery_config.json is %{public}d", isOpen); 102 103 if (isOpen) { 104 return true; 105 } 106 107 ifsConf.open(SYSTEM_POWER_CONFIG_PATH); 108 isOpen = ifsConf.is_open(); 109 HDF_LOGI("open then system battery_config.json is %{public}d", isOpen); 110 return isOpen; 111} 112 113void PowerConfig::ParseConfInner(const Json::Value& config) 114{ 115 HDF_LOGI("start parse power config inner"); 116 ParseSceneConfig(GetValue(config, "scene")); 117} 118 119bool PowerConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const 120{ 121 SplitStr(TrimStr(key), ".", keys); 122 return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true; 123} 124 125Json::Value PowerConfig::GetValue(const Json::Value& config, std::string key) const 126{ 127 std::vector<std::string> keys; 128 if (!SplitKey(key, keys)) { 129 HDF_LOGW("The key does not meet the. key=%{public}s", key.c_str()); 130 return Json::Value(); 131 } 132 133 std::string firstKey = keys[MAP_KEY_INDEX]; 134 Json::Value value = (config.isObject() && config.isMember(firstKey)) ? config[firstKey] : Json::Value(); 135 if (value.isNull()) { 136 HDF_LOGW("Value is empty. key=%{public}s", keys[MAP_KEY_INDEX].c_str()); 137 return value; 138 } 139 140 for (size_t i = 1; i < keys.size(); ++i) { 141 if (!value.isObject() || !value.isMember(keys[i])) { 142 HDF_LOGW("The key is not configured. key=%{public}s", keys[i].c_str()); 143 break; 144 } 145 value = value[keys[i]]; 146 } 147 return value; 148} 149 150void PowerConfig::ParseSceneConfig(const Json::Value& sceneConfig) 151{ 152 if (sceneConfig.isNull() || !sceneConfig.isObject()) { 153 HDF_LOGW("sceneConfig is invalid"); 154 return; 155 } 156 157 sceneConfigMap_.clear(); 158 Json::Value::Members members = sceneConfig.getMemberNames(); 159 for (auto iter = members.begin(); iter != members.end(); iter++) { 160 std::string key = *iter; 161 Json::Value valueObj = sceneConfig[key]; 162 if (key.empty() || valueObj.isNull() || !valueObj.isObject()) { 163 HDF_LOGW("The scene config is invalid, key=%{public}s", key.c_str()); 164 continue; 165 } 166 167 PowerConfig::PowerSceneConfig tempPowerSceneConfig; 168 Json::Value getPath = GetValue(valueObj, "get.path"); 169 Json::Value setPath = GetValue(valueObj, "set.path"); 170 if (isValidJsonString(getPath)) { 171 tempPowerSceneConfig.getPath = getPath.asString(); 172 HDF_LOGI("getPath key=%{public}s", tempPowerSceneConfig.getPath.c_str()); 173 } 174 if (isValidJsonString(setPath)) { 175 tempPowerSceneConfig.setPath = setPath.asString(); 176 HDF_LOGI("setPath key=%{public}s", tempPowerSceneConfig.setPath.c_str()); 177 } 178 179 sceneConfigMap_.insert(std::make_pair(key, tempPowerSceneConfig)); 180 } 181 HDF_LOGI("The charge scene config size: %{public}d", 182 static_cast<int32_t>(sceneConfigMap_.size())); 183} 184 185bool PowerConfig::isValidJsonString(const Json::Value& config) const 186{ 187 return !config.isNull() && config.isString(); 188} 189 190} // namespace V1_2 191} // namespace Power 192} // namespace HDI 193} // namespace OHOS