• 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_mgr_cjson_utils.h"
19 #include "string_ex.h"
20 #include "config_policy_utils.h"
21 #include "charger_log.h"
22 
23 namespace OHOS {
24 namespace PowerMgr {
25 namespace {
26 constexpr const char* BATTERY_CONFIG_PATH = "etc/battery/battery_config.json";
27 constexpr const char* SYSTEM_BATTERY_CONFIG_PATH = "/system/etc/battery/battery_config.json";
28 constexpr const char* VENDOR_BATTERY_CONFIG_PATH = "/vendor/etc/battery/battery_config.json";
29 constexpr const char* BATTERY_CONFIG_EXCEPTION_PATH = "";
30 constexpr int32_t MAP_KEY_INDEX = 0;
31 constexpr int32_t BEGIN_SOC_INDEX = 0;
32 constexpr int32_t END_SOC_INDEX = 1;
33 constexpr int32_t MAX_SOC_RANGE = 2;
34 constexpr int32_t RED_INDEX = 0;
35 constexpr int32_t GREEN_INDEX = 1;
36 constexpr int32_t BLUE_INDEX = 2;
37 constexpr int32_t MAX_RGB_RANGE = 3;
38 constexpr int32_t MAX_DEPTH = 5;
39 constexpr int32_t MIN_DEPTH = 1;
40 constexpr uint32_t MOVE_LEFT_16 = 16;
41 constexpr uint32_t MOVE_LEFT_8 = 8;
42 } // namespace
43 std::shared_ptr<BatteryConfig> BatteryConfig::instance_ = nullptr;
44 std::mutex BatteryConfig::mutex_;
45 
GetInstance()46 BatteryConfig& BatteryConfig::GetInstance()
47 {
48     std::lock_guard<std::mutex> lock(mutex_);
49     if (instance_ == nullptr) {
50         instance_ = std::make_shared<BatteryConfig>();
51     }
52     return *(instance_.get());
53 }
54 
ParseConfig()55 bool BatteryConfig::ParseConfig()
56 {
57     char buf[MAX_PATH_LEN];
58     char* path = GetOneCfgFile(BATTERY_CONFIG_PATH, buf, MAX_PATH_LEN);
59     if (path == nullptr || *path == '\0') {
60         BATTERY_HILOGW(FEATURE_CHARGING, "GetOneCfgFile battery_config.json is NULL");
61         path = const_cast<char*>(BATTERY_CONFIG_EXCEPTION_PATH);
62     }
63     BATTERY_HILOGD(FEATURE_CHARGING, "GetOneCfgFile battery_config.json");
64 
65     std::ifstream ifsConf;
66     if (!OpenFile(ifsConf, path)) {
67         return false;
68     }
69 
70     if (config_) {
71         cJSON_Delete(config_);
72         config_ = nullptr;
73     }
74 
75     std::string content((std::istreambuf_iterator<char>(ifsConf)), std::istreambuf_iterator<char>());
76     config_ = cJSON_Parse(content.c_str());
77     ifsConf.close();
78     if (config_ == nullptr) {
79         const char* errorPtr = cJSON_GetErrorPtr();
80         BATTERY_HILOGW(FEATURE_CHARGING, "cJSON parse error: in %{public}s",
81             (errorPtr != nullptr) ? errorPtr : "unknown error");
82         return false;
83     }
84 
85     if (BatteryMgrJsonUtils::IsEmptyJsonParse(config_)) {
86         cJSON_Delete(config_);
87         config_ = nullptr;
88         BATTERY_HILOGW(FEATURE_CHARGING, "cJSON parse result is empty, battery config is %{public}s", content.c_str());
89         return false;
90     } else {
91         ParseConfInner();
92     }
93     return true;
94 }
95 
IsExist(std::string key) const96 bool BatteryConfig::IsExist(std::string key) const
97 {
98     cJSON* value = GetValue(key);
99     return (value && !cJSON_IsNull(value));
100 }
101 
GetInt(std::string key,int32_t defVal) const102 int32_t BatteryConfig::GetInt(std::string key, int32_t defVal) const
103 {
104     cJSON* value = GetValue(key);
105     return (!BatteryMgrJsonUtils::IsValidJsonNumber(value)) ? defVal : static_cast<int32_t>(value->valueint);
106 }
107 
GetString(std::string key,std::string defVal) const108 std::string BatteryConfig::GetString(std::string key, std::string defVal) const
109 {
110     cJSON* value = GetValue(key);
111     return (!BatteryMgrJsonUtils::IsValidJsonString(value)) ? defVal : value->valuestring;
112 }
113 
GetLightConf() const114 const std::vector<BatteryConfig::LightConf>& BatteryConfig::GetLightConf() const
115 {
116     return lightConf_;
117 }
118 
DestroyInstance()119 void BatteryConfig::DestroyInstance()
120 {
121     std::lock_guard<std::mutex> lock(mutex_);
122     instance_ = nullptr;
123 }
124 
OpenFile(std::ifstream & ifsConf,const std::string & configPath)125 bool BatteryConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath)
126 {
127     bool isOpen = false;
128     if (!configPath.empty()) {
129         ifsConf.open(configPath);
130         isOpen = ifsConf.is_open();
131         BATTERY_HILOGD(FEATURE_CHARGING, "open configPath file is %{public}d", isOpen);
132     }
133     if (isOpen) {
134         return true;
135     }
136 
137     ifsConf.open(VENDOR_BATTERY_CONFIG_PATH);
138     isOpen = ifsConf.is_open();
139     BATTERY_HILOGI(FEATURE_CHARGING, "open then vendor battery_config.json is %{public}d", isOpen);
140 
141     if (isOpen) {
142         return true;
143     }
144 
145     ifsConf.open(SYSTEM_BATTERY_CONFIG_PATH);
146     isOpen = ifsConf.is_open();
147     BATTERY_HILOGI(FEATURE_CHARGING, "open then system battery_config.json is %{public}d", isOpen);
148     return isOpen;
149 }
150 
ParseConfInner()151 void BatteryConfig::ParseConfInner()
152 {
153     lightConf_.clear();
154     ParseLightConf("low");
155     ParseLightConf("normal");
156     ParseLightConf("high");
157     BATTERY_HILOGD(FEATURE_CHARGING, "The battery light configuration size %{public}d",
158         static_cast<int32_t>(lightConf_.size()));
159 }
160 
ParseLightConf(std::string level)161 void BatteryConfig::ParseLightConf(std::string level)
162 {
163     cJSON* soc = GetValue("light." + level + ".soc");
164     cJSON* rgb = GetValue("light." + level + ".rgb");
165     if (!BatteryMgrJsonUtils::IsValidJsonArray(soc) || !BatteryMgrJsonUtils::IsValidJsonArray(rgb)) {
166         BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s configuration is invalid.", level.c_str());
167         return;
168     }
169     if (cJSON_GetArraySize(soc) != MAX_SOC_RANGE) {
170         BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s soc data length error.", level.c_str());
171         return;
172     }
173     cJSON* beginSocItem = cJSON_GetArrayItem(soc, BEGIN_SOC_INDEX);
174     cJSON* endSocItem = cJSON_GetArrayItem(soc, END_SOC_INDEX);
175     if (!BatteryMgrJsonUtils::IsValidJsonNumber(beginSocItem) || !BatteryMgrJsonUtils::IsValidJsonNumber(endSocItem)) {
176         BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s soc data type error.", level.c_str());
177         return;
178     }
179     if (cJSON_GetArraySize(rgb) != MAX_RGB_RANGE) {
180         BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s rgb data length error.", level.c_str());
181         return;
182     }
183     cJSON* redItem = cJSON_GetArrayItem(rgb, RED_INDEX);
184     cJSON* greenItem = cJSON_GetArrayItem(rgb, GREEN_INDEX);
185     cJSON* blueItem = cJSON_GetArrayItem(rgb, BLUE_INDEX);
186     if (!BatteryMgrJsonUtils::IsValidJsonNumber(redItem) || !BatteryMgrJsonUtils::IsValidJsonNumber(greenItem) ||
187         !BatteryMgrJsonUtils::IsValidJsonNumber(blueItem)) {
188         BATTERY_HILOGW(FEATURE_CHARGING, "The battery light %{public}s rgb data type error.", level.c_str());
189         return;
190     }
191     BatteryConfig::LightConf lightConf = {
192         .beginSoc = static_cast<int32_t>(beginSocItem->valueint),
193         .endSoc = static_cast<int32_t>(endSocItem->valueint),
194         .rgb = (static_cast<uint32_t>(redItem->valueint) << MOVE_LEFT_16) |
195                (static_cast<uint32_t>(greenItem->valueint) << MOVE_LEFT_8) |
196                static_cast<uint32_t>(blueItem->valueint)
197     };
198     lightConf_.push_back(lightConf);
199 }
200 
FindConf(const std::string & key) const201 cJSON* BatteryConfig::FindConf(const std::string& key) const
202 {
203     return (config_ && cJSON_IsObject(config_) && cJSON_HasObjectItem(config_, key.c_str())) ?
204         cJSON_GetObjectItemCaseSensitive(config_, key.c_str()) : nullptr;
205 }
206 
SplitKey(const std::string & key,std::vector<std::string> & keys) const207 bool BatteryConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const
208 {
209     SplitStr(TrimStr(key), ".", keys);
210     return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true;
211 }
212 
GetValue(std::string key) const213 cJSON* BatteryConfig::GetValue(std::string key) const
214 {
215     std::vector<std::string> keys;
216     if (!SplitKey(key, keys)) {
217         BATTERY_HILOGW(FEATURE_CHARGING, "The key does not meet the. key=%{public}s", key.c_str());
218         return nullptr;
219     }
220 
221     cJSON* value = FindConf(keys[MAP_KEY_INDEX]);
222     if (!value || cJSON_IsNull(value)) {
223         BATTERY_HILOGD(FEATURE_CHARGING, "Value is empty. key=%{public}s", key.c_str());
224         return value;
225     }
226 
227     for (size_t i = 1; i < keys.size(); ++i) {
228         if (!cJSON_IsObject(value) || !cJSON_HasObjectItem(value, keys[i].c_str())) {
229             BATTERY_HILOGW(FEATURE_CHARGING, "The key is not configured. key=%{public}s", keys[i].c_str());
230             break;
231         }
232         value = cJSON_GetObjectItemCaseSensitive(value, keys[i].c_str());
233     }
234     return value;
235 }
236 } // namespace PowerMgr
237 } // namespace OHOS
238