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