• 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 "string_ex.h"
19 #include "config_policy_utils.h"
20 
21 #include "battery_log.h"
22 #include "power_common.h"
23 
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 constexpr int32_t FIRST_BUTTON_INDEX = 0;
42 constexpr int32_t SECOND_BUTTON_INDEX = 1;
43 constexpr int32_t MAX_BUTTON_RANGE = 2;
44 }
45 namespace OHOS {
46 namespace PowerMgr {
47 std::shared_ptr<BatteryConfig> BatteryConfig::instance_ = nullptr;
48 std::mutex BatteryConfig::mutex_;
49 
GetInstance()50 BatteryConfig& BatteryConfig::GetInstance()
51 {
52     std::lock_guard<std::mutex> lock(mutex_);
53     if (instance_ == nullptr) {
54         instance_ = std::make_shared<BatteryConfig>();
55     }
56     return *(instance_.get());
57 }
58 
ParseConfig()59 bool 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(COMP_SVC, "GetOneCfgFile battery_config.json is NULL");
65         path = const_cast<char*>(BATTERY_CONFIG_EXCEPTION_PATH);
66     }
67     BATTERY_HILOGD(COMP_SVC, "GetOneCfgFile battery_config.json");
68 
69     Json::CharReaderBuilder readerBuilder;
70     std::ifstream ifsConf;
71 
72     RETURN_IF_WITH_RET(!OpenFile(ifsConf, path), false);
73 
74     config_.clear();
75     readerBuilder["collectComments"] = false;
76     JSONCPP_STRING errs;
77 
78     if (parseFromStream(readerBuilder, ifsConf, &config_, &errs) && !config_.empty()) {
79         ParseConfInner();
80     }
81     ifsConf.close();
82     return true;
83 }
84 
IsExist(std::string key) const85 bool BatteryConfig::IsExist(std::string key) const
86 {
87     return !GetValue(key).isNull();
88 }
89 
GetInt(std::string key,int32_t defVal) const90 int32_t BatteryConfig::GetInt(std::string key, int32_t defVal) const
91 {
92     Json::Value value = GetValue(key);
93     return (value.isNull() || !value.isInt()) ? defVal : value.asInt();
94 }
95 
GetLightConf() const96 const std::vector<BatteryConfig::LightConf>& BatteryConfig::GetLightConf() const
97 {
98     return lightConf_;
99 }
100 
GetWirelessChargerConf() const101 bool BatteryConfig::GetWirelessChargerConf() const
102 {
103     return wirelessChargerEnable_;
104 }
105 
GetCommonEventConf() const106 const std::vector<BatteryConfig::CommonEventConf>& BatteryConfig::GetCommonEventConf() const
107 {
108     return commonEventConf_;
109 }
110 
OpenFile(std::ifstream & ifsConf,const std::string & configPath)111 bool BatteryConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath)
112 {
113     bool isOpen = false;
114     if (!configPath.empty()) {
115         ifsConf.open(configPath);
116         isOpen = ifsConf.is_open();
117         BATTERY_HILOGD(COMP_SVC, "open configPath file is %{public}d", isOpen);
118     }
119     RETURN_IF_WITH_RET(isOpen, true);
120 
121     ifsConf.open(VENDOR_BATTERY_CONFIG_PATH);
122     isOpen = ifsConf.is_open();
123     BATTERY_HILOGI(COMP_SVC, "open then vendor battery_config.json is %{public}d", isOpen);
124     RETURN_IF_WITH_RET(isOpen, true);
125 
126     ifsConf.open(SYSTEM_BATTERY_CONFIG_PATH);
127     isOpen = ifsConf.is_open();
128     BATTERY_HILOGI(COMP_SVC, "open then system battery_config.json is %{public}d", isOpen);
129     return isOpen;
130 }
131 
ParseConfInner()132 void BatteryConfig::ParseConfInner()
133 {
134     lightConf_.clear();
135     ParseLightConf("low");
136     ParseLightConf("normal");
137     ParseLightConf("high");
138     BATTERY_HILOGD(COMP_SVC, "The battery light configuration size %{public}d",
139         static_cast<int32_t>(lightConf_.size()));
140     ParseWirelessChargerConf();
141     ParseBootActionsConf();
142     ParsePopupConf();
143     ParseNotificationConf();
144 }
145 
ParseLightConf(std::string level)146 void BatteryConfig::ParseLightConf(std::string level)
147 {
148     Json::Value soc = GetValue("light." + level + ".soc");
149     Json::Value rgb = GetValue("light." + level + ".rgb");
150     if (!soc.isArray() || !rgb.isArray()) {
151         BATTERY_HILOGW(COMP_SVC, "The battery light %{public}s configuration is invalid.", level.c_str());
152         return;
153     }
154 
155     if (soc.size() != MAX_SOC_RANGE || !soc[BEGIN_SOC_INDEX].isInt() || !soc[END_SOC_INDEX].isInt()) {
156         BATTERY_HILOGW(COMP_SVC, "The battery light %{public}s soc data type error.", level.c_str());
157         return;
158     }
159     if (rgb.size() != MAX_RGB_RANGE || !rgb[RED_INDEX].isUInt() || !rgb[GREEN_INDEX].isUInt() ||
160         !rgb[BLUE_INDEX].isUInt()) {
161         BATTERY_HILOGW(COMP_SVC, "The battery light %{public}s rgb data type error.", level.c_str());
162         return;
163     }
164     BatteryConfig::LightConf lightConf = {
165         .beginSoc = soc[BEGIN_SOC_INDEX].asInt(),
166         .endSoc = soc[END_SOC_INDEX].asInt(),
167         .rgb = (rgb[RED_INDEX].asUInt() << MOVE_LEFT_16) |
168                (rgb[GREEN_INDEX].asUInt() << MOVE_LEFT_8) |
169                rgb[BLUE_INDEX].asUInt()
170     };
171     lightConf_.push_back(lightConf);
172 }
173 
ParseWirelessChargerConf()174 void BatteryConfig::ParseWirelessChargerConf()
175 {
176     Json::Value wirelessCharger = GetValue("wirelesscharger");
177     if (wirelessCharger.isNull() || !wirelessCharger.isInt()) {
178         BATTERY_HILOGW(COMP_SVC, "wirelesscharger is invalid");
179         return;
180     }
181     wirelessChargerEnable_ = static_cast<bool>(wirelessCharger.asInt());
182 }
183 
ParseBootActionsConf()184 void BatteryConfig::ParseBootActionsConf()
185 {
186     Json::Value bootActionsConfig = GetValue("boot_actions");
187     if (bootActionsConfig.isNull() || !bootActionsConfig.isObject()) {
188         BATTERY_HILOGW(COMP_SVC, "boot_actions is invalid");
189         return;
190     }
191     ParseCommonEventConf(bootActionsConfig);
192 }
193 
ParseCommonEventConf(const Json::Value & bootActionsConfig)194 void BatteryConfig::ParseCommonEventConf(const Json::Value& bootActionsConfig)
195 {
196     Json::Value commonEventConfs = bootActionsConfig["sendcommonevent"];
197     if (commonEventConfs.isNull() || !commonEventConfs.isArray()) {
198         BATTERY_HILOGW(COMP_SVC, "The common event config is invalid");
199         return;
200     }
201     commonEventConf_.clear();
202     for (const auto& commonEventConf : commonEventConfs) {
203         BatteryConfig::CommonEventConf tempCommonEventConf;
204         Json::Value eventName = commonEventConf["event_name"];
205         Json::Value sceneConfigName = commonEventConf["scene_config"]["name"];
206         Json::Value sceneConfigEqual = commonEventConf["scene_config"]["equal"];
207         Json::Value sceneConfigNotEqual = commonEventConf["scene_config"]["not_equal"];
208         Json::Value uevent = commonEventConf["uevent"];
209         if (!eventName.isString() || !sceneConfigName.isString() || !uevent.isString()) {
210             BATTERY_HILOGW(COMP_SVC, "parse common event config failed");
211             continue;
212         }
213         if (!sceneConfigEqual.isNull() && sceneConfigEqual.isString()) {
214             tempCommonEventConf.sceneConfigEqual = true;
215             tempCommonEventConf.sceneConfigValue = sceneConfigEqual.asString();
216         } else if (!sceneConfigNotEqual.isNull() && sceneConfigNotEqual.isString()) {
217             tempCommonEventConf.sceneConfigEqual = false;
218             tempCommonEventConf.sceneConfigValue = sceneConfigNotEqual.asString();
219         } else {
220             BATTERY_HILOGW(COMP_SVC, "parse expect value failed");
221             continue;
222         }
223         tempCommonEventConf.eventName = eventName.asString();
224         tempCommonEventConf.sceneConfigName = sceneConfigName.asString();
225         tempCommonEventConf.uevent = uevent.asString();
226         commonEventConf_.push_back(tempCommonEventConf);
227     }
228     BATTERY_HILOGI(COMP_SVC, "The battery commonevent configuration size %{public}d",
229         static_cast<int32_t>(commonEventConf_.size()));
230 }
231 
GetPopupConf() const232 const std::unordered_map<std::string, std::vector<BatteryConfig::PopupConf>>& BatteryConfig::GetPopupConf() const
233 {
234     BATTERY_HILOGI(COMP_SVC, "GetPopupConf");
235     return popupConfig_;
236 }
237 
ParsePopupConf()238 void BatteryConfig::ParsePopupConf()
239 {
240     Json::Value popupConfig = GetValue("popup");
241     if (popupConfig.isNull() || !popupConfig.isObject()) {
242         BATTERY_HILOGW(COMP_SVC, "popupConfig invalid");
243         return;
244     }
245     popupConfig_.clear();
246     Json::Value::Members members = popupConfig.getMemberNames();
247     for (auto iter = members.begin(); iter != members.end(); iter++) {
248         std::string uevent = *iter;
249         Json::Value valueObj = popupConfig[uevent];
250         if (valueObj.isNull() || !valueObj.isArray()) {
251             BATTERY_HILOGW(COMP_SVC, "ueventConf invalid, key=%{public}s", uevent.c_str());
252             continue;
253         }
254         std::vector<BatteryConfig::PopupConf> popupConfVec;
255         for (const auto& popupObj : valueObj) {
256             Json::Value popupName = popupObj["name"];
257             Json::Value popupAction = popupObj["action"];
258             if (!popupName.isString() || !popupAction.isUInt()) {
259                 BATTERY_HILOGW(COMP_SVC, "popupObj invalid, key=%{public}s", uevent.c_str());
260                 continue;
261             }
262             BatteryConfig::PopupConf popupCfg = {
263                 .name = popupName.asString(),
264                 .action = popupAction.asUInt()
265             };
266             BATTERY_HILOGI(COMP_SVC, "add popupConf %{public}s, %{public}d", popupCfg.name.c_str(), popupCfg.action);
267             popupConfVec.emplace_back(popupCfg);
268         }
269         BATTERY_HILOGI(COMP_SVC, "popupConfVec size: %{public}d", static_cast<int32_t>(popupConfVec.size()));
270         popupConfig_.emplace(uevent, popupConfVec);
271     }
272     BATTERY_HILOGI(COMP_SVC, "popupConfVec size: %{public}d", static_cast<int32_t>(popupConfig_.size()));
273 }
274 
GetNotificationConf() const275 const std::unordered_map<std::string, BatteryConfig::NotificationConf>& BatteryConfig::GetNotificationConf() const
276 {
277     return notificationConfMap_;
278 }
279 
ParseNotificationConf()280 void BatteryConfig::ParseNotificationConf()
281 {
282     Json::Value nConf = GetValue("notification");
283     if (nConf.isNull() || !nConf.isArray()) {
284         BATTERY_HILOGW(COMP_SVC, "nConf is invalid");
285         return;
286     }
287     for (const auto& conf : nConf) {
288         Json::Value nameObj = conf["name"];
289         Json::Value iconObj = conf["icon"];
290         Json::Value titleObj = conf["title"];
291         Json::Value textObj = conf["text"];
292         Json::Value buttonObj = conf["button"];
293         if (!nameObj.isString() || !iconObj.isString() || !titleObj.isString()
294             || !textObj.isString() || !buttonObj.isArray()) {
295             BATTERY_HILOGW(COMP_SVC, "stringConf Parse failed");
296             continue;
297         }
298         if (buttonObj.size() != MAX_BUTTON_RANGE || !buttonObj[FIRST_BUTTON_INDEX].isObject() ||
299             !buttonObj[SECOND_BUTTON_INDEX].isObject()) {
300             BATTERY_HILOGW(COMP_SVC, "buttonConf is invalid");
301             continue;
302         }
303         Json::Value firstButtonNameObj = buttonObj[FIRST_BUTTON_INDEX]["name"];
304         Json::Value firstButtonActionObj = buttonObj[FIRST_BUTTON_INDEX]["action"];
305         Json::Value secondButtonNameObj = buttonObj[SECOND_BUTTON_INDEX]["name"];
306         Json::Value secondButtonActionObj = buttonObj[SECOND_BUTTON_INDEX]["action"];
307         if (!firstButtonNameObj.isString() || !firstButtonActionObj.isString()
308             || !secondButtonNameObj.isString() || !secondButtonActionObj.isString()) {
309             BATTERY_HILOGW(COMP_SVC, "buttonConf Parse failed");
310             return;
311         }
312         std::string name = nameObj.asString();
313         BatteryConfig::NotificationConf notificationConf = {
314             .name = name,
315             .icon = iconObj.asString(),
316             .title = titleObj.asString(),
317             .text = textObj.asString(),
318             .firstButton = std::make_pair(firstButtonNameObj.asString(), firstButtonActionObj.asString()),
319             .secondButton = std::make_pair(secondButtonNameObj.asString(), secondButtonActionObj.asString())
320         };
321         BATTERY_HILOGI(COMP_SVC, "notificationConf name: %{public}s", name.c_str());
322         notificationConfMap_.emplace(name, notificationConf);
323     }
324     BATTERY_HILOGI(COMP_SVC, "notificationConf size: %{public}d", static_cast<int32_t>(notificationConfMap_.size()));
325 }
326 
FindConf(const std::string & key) const327 Json::Value BatteryConfig::FindConf(const std::string& key) const
328 {
329     return (config_.isObject() && config_.isMember(key)) ? config_[key] : Json::Value();
330 }
331 
SplitKey(const std::string & key,std::vector<std::string> & keys) const332 bool BatteryConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const
333 {
334     SplitStr(TrimStr(key), ".", keys);
335     return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true;
336 }
337 
GetValue(std::string key) const338 Json::Value BatteryConfig::GetValue(std::string key) const
339 {
340     std::vector<std::string> keys;
341     if (!SplitKey(key, keys)) {
342         BATTERY_HILOGW(COMP_SVC, "The key does not meet the. key=%{public}s", key.c_str());
343         return Json::Value();
344     }
345 
346     Json::Value value = FindConf(keys[MAP_KEY_INDEX]);
347     if (value.isNull()) {
348         BATTERY_HILOGD(COMP_SVC, "Value is empty. key=%{public}s", key.c_str());
349         return value;
350     }
351 
352     for (size_t i = 1; i < keys.size(); ++i) {
353         if (!value.isObject() || !value.isMember(keys[i])) {
354             BATTERY_HILOGW(COMP_SVC, "The key is not configured. key=%{public}s", keys[i].c_str());
355             break;
356         }
357         value = value[keys[i]];
358     }
359     return value;
360 }
361 } // namespace PowerMgr
362 } // namespace OHOS
363