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