1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "power_config.h"
17094332d3Sopenharmony_ci#include "string_ex.h"
18094332d3Sopenharmony_ci#include "config_policy_utils.h"
19094332d3Sopenharmony_ci#include "power_hdf_log.h"
20094332d3Sopenharmony_ci
21094332d3Sopenharmony_cinamespace OHOS {
22094332d3Sopenharmony_cinamespace HDI {
23094332d3Sopenharmony_cinamespace Power {
24094332d3Sopenharmony_cinamespace V1_2 {
25094332d3Sopenharmony_cinamespace {
26094332d3Sopenharmony_ciconstexpr const char* POWER_CONFIG_PATH = "etc/power_config/power_config.json";
27094332d3Sopenharmony_ciconstexpr const char* SYSTEM_POWER_CONFIG_PATH = "/system/etc/power_config/power_config.json";
28094332d3Sopenharmony_ciconstexpr const char* VENDOR_POWER_CONFIG_PATH = "/vendor/etc/power_config/power_config.json";
29094332d3Sopenharmony_ciconstexpr const char* POWER_CONFIG_EXCEPTION_PATH = "";
30094332d3Sopenharmony_ciconstexpr int32_t MAP_KEY_INDEX = 0;
31094332d3Sopenharmony_ciconstexpr int32_t MAX_DEPTH = 5;
32094332d3Sopenharmony_ciconstexpr int32_t MIN_DEPTH = 1;
33094332d3Sopenharmony_ci}
34094332d3Sopenharmony_ci
35094332d3Sopenharmony_cistd::shared_ptr<PowerConfig> PowerConfig::instance_ = nullptr;
36094332d3Sopenharmony_cistd::mutex PowerConfig::mutex_;
37094332d3Sopenharmony_ci
38094332d3Sopenharmony_ciPowerConfig& PowerConfig::GetInstance()
39094332d3Sopenharmony_ci{
40094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
41094332d3Sopenharmony_ci    if (instance_ == nullptr) {
42094332d3Sopenharmony_ci        instance_ = std::make_shared<PowerConfig>();
43094332d3Sopenharmony_ci    }
44094332d3Sopenharmony_ci    return *(instance_.get());
45094332d3Sopenharmony_ci}
46094332d3Sopenharmony_ci
47094332d3Sopenharmony_civoid PowerConfig::DestroyInstance()
48094332d3Sopenharmony_ci{
49094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
50094332d3Sopenharmony_ci    instance_ = nullptr;
51094332d3Sopenharmony_ci}
52094332d3Sopenharmony_ci
53094332d3Sopenharmony_ciconst std::map<std::string, PowerConfig::PowerSceneConfig>& PowerConfig::GetPowerSceneConfigMap() const
54094332d3Sopenharmony_ci{
55094332d3Sopenharmony_ci    return sceneConfigMap_;
56094332d3Sopenharmony_ci}
57094332d3Sopenharmony_ci
58094332d3Sopenharmony_cibool PowerConfig::ParseConfig()
59094332d3Sopenharmony_ci{
60094332d3Sopenharmony_ci    char buf[MAX_PATH_LEN];
61094332d3Sopenharmony_ci    char* path = GetOneCfgFile(POWER_CONFIG_PATH, buf, MAX_PATH_LEN);
62094332d3Sopenharmony_ci    if (path == nullptr || *path == '\0') {
63094332d3Sopenharmony_ci        HDF_LOGW("GetOneCfgFile power_config.json is NULL");
64094332d3Sopenharmony_ci        path = const_cast<char*>(POWER_CONFIG_EXCEPTION_PATH);
65094332d3Sopenharmony_ci    }
66094332d3Sopenharmony_ci    HDF_LOGI("GetOneCfgFile power_config.json");
67094332d3Sopenharmony_ci
68094332d3Sopenharmony_ci    Json::CharReaderBuilder readerBuilder;
69094332d3Sopenharmony_ci    std::ifstream ifsConf;
70094332d3Sopenharmony_ci
71094332d3Sopenharmony_ci    if (!OpenFile(ifsConf, path)) {
72094332d3Sopenharmony_ci        return false;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci
75094332d3Sopenharmony_ci    Json::Value config;
76094332d3Sopenharmony_ci    readerBuilder["collectComments"] = false;
77094332d3Sopenharmony_ci    JSONCPP_STRING errs;
78094332d3Sopenharmony_ci
79094332d3Sopenharmony_ci    if (parseFromStream(readerBuilder, ifsConf, &config, &errs) && !config.empty()) {
80094332d3Sopenharmony_ci        ParseConfInner(config);
81094332d3Sopenharmony_ci    }
82094332d3Sopenharmony_ci    ifsConf.close();
83094332d3Sopenharmony_ci    return true;
84094332d3Sopenharmony_ci}
85094332d3Sopenharmony_ci
86094332d3Sopenharmony_cibool PowerConfig::OpenFile(std::ifstream& ifsConf, const std::string& configPath)
87094332d3Sopenharmony_ci{
88094332d3Sopenharmony_ci    bool isOpen = false;
89094332d3Sopenharmony_ci    if (!configPath.empty()) {
90094332d3Sopenharmony_ci        ifsConf.open(configPath);
91094332d3Sopenharmony_ci        isOpen = ifsConf.is_open();
92094332d3Sopenharmony_ci        HDF_LOGI("path is %{public}s", configPath.c_str());
93094332d3Sopenharmony_ci        HDF_LOGI("open file is %{public}d", isOpen);
94094332d3Sopenharmony_ci    }
95094332d3Sopenharmony_ci    if (isOpen) {
96094332d3Sopenharmony_ci        return true;
97094332d3Sopenharmony_ci    }
98094332d3Sopenharmony_ci
99094332d3Sopenharmony_ci    ifsConf.open(VENDOR_POWER_CONFIG_PATH);
100094332d3Sopenharmony_ci    isOpen = ifsConf.is_open();
101094332d3Sopenharmony_ci    HDF_LOGI("open then vendor battery_config.json is %{public}d", isOpen);
102094332d3Sopenharmony_ci
103094332d3Sopenharmony_ci    if (isOpen) {
104094332d3Sopenharmony_ci        return true;
105094332d3Sopenharmony_ci    }
106094332d3Sopenharmony_ci
107094332d3Sopenharmony_ci    ifsConf.open(SYSTEM_POWER_CONFIG_PATH);
108094332d3Sopenharmony_ci    isOpen = ifsConf.is_open();
109094332d3Sopenharmony_ci    HDF_LOGI("open then system battery_config.json is %{public}d", isOpen);
110094332d3Sopenharmony_ci    return isOpen;
111094332d3Sopenharmony_ci}
112094332d3Sopenharmony_ci
113094332d3Sopenharmony_civoid PowerConfig::ParseConfInner(const Json::Value& config)
114094332d3Sopenharmony_ci{
115094332d3Sopenharmony_ci    HDF_LOGI("start parse power config inner");
116094332d3Sopenharmony_ci    ParseSceneConfig(GetValue(config, "scene"));
117094332d3Sopenharmony_ci}
118094332d3Sopenharmony_ci
119094332d3Sopenharmony_cibool PowerConfig::SplitKey(const std::string& key, std::vector<std::string>& keys) const
120094332d3Sopenharmony_ci{
121094332d3Sopenharmony_ci    SplitStr(TrimStr(key), ".", keys);
122094332d3Sopenharmony_ci    return (keys.size() < MIN_DEPTH || keys.size() > MAX_DEPTH) ? false : true;
123094332d3Sopenharmony_ci}
124094332d3Sopenharmony_ci
125094332d3Sopenharmony_ciJson::Value PowerConfig::GetValue(const Json::Value& config, std::string key) const
126094332d3Sopenharmony_ci{
127094332d3Sopenharmony_ci    std::vector<std::string> keys;
128094332d3Sopenharmony_ci    if (!SplitKey(key, keys)) {
129094332d3Sopenharmony_ci        HDF_LOGW("The key does not meet the. key=%{public}s", key.c_str());
130094332d3Sopenharmony_ci        return Json::Value();
131094332d3Sopenharmony_ci    }
132094332d3Sopenharmony_ci
133094332d3Sopenharmony_ci    std::string firstKey = keys[MAP_KEY_INDEX];
134094332d3Sopenharmony_ci    Json::Value value = (config.isObject() && config.isMember(firstKey)) ? config[firstKey] : Json::Value();
135094332d3Sopenharmony_ci    if (value.isNull()) {
136094332d3Sopenharmony_ci        HDF_LOGW("Value is empty. key=%{public}s", keys[MAP_KEY_INDEX].c_str());
137094332d3Sopenharmony_ci        return value;
138094332d3Sopenharmony_ci    }
139094332d3Sopenharmony_ci
140094332d3Sopenharmony_ci    for (size_t i = 1; i < keys.size(); ++i) {
141094332d3Sopenharmony_ci        if (!value.isObject() || !value.isMember(keys[i])) {
142094332d3Sopenharmony_ci            HDF_LOGW("The key is not configured. key=%{public}s", keys[i].c_str());
143094332d3Sopenharmony_ci            break;
144094332d3Sopenharmony_ci        }
145094332d3Sopenharmony_ci        value = value[keys[i]];
146094332d3Sopenharmony_ci    }
147094332d3Sopenharmony_ci    return value;
148094332d3Sopenharmony_ci}
149094332d3Sopenharmony_ci
150094332d3Sopenharmony_civoid PowerConfig::ParseSceneConfig(const Json::Value& sceneConfig)
151094332d3Sopenharmony_ci{
152094332d3Sopenharmony_ci    if (sceneConfig.isNull() || !sceneConfig.isObject()) {
153094332d3Sopenharmony_ci        HDF_LOGW("sceneConfig is invalid");
154094332d3Sopenharmony_ci        return;
155094332d3Sopenharmony_ci    }
156094332d3Sopenharmony_ci
157094332d3Sopenharmony_ci    sceneConfigMap_.clear();
158094332d3Sopenharmony_ci    Json::Value::Members members = sceneConfig.getMemberNames();
159094332d3Sopenharmony_ci    for (auto iter = members.begin(); iter != members.end(); iter++) {
160094332d3Sopenharmony_ci        std::string key = *iter;
161094332d3Sopenharmony_ci        Json::Value valueObj = sceneConfig[key];
162094332d3Sopenharmony_ci        if (key.empty() || valueObj.isNull() || !valueObj.isObject()) {
163094332d3Sopenharmony_ci            HDF_LOGW("The scene config is invalid, key=%{public}s", key.c_str());
164094332d3Sopenharmony_ci            continue;
165094332d3Sopenharmony_ci        }
166094332d3Sopenharmony_ci
167094332d3Sopenharmony_ci        PowerConfig::PowerSceneConfig tempPowerSceneConfig;
168094332d3Sopenharmony_ci        Json::Value getPath = GetValue(valueObj, "get.path");
169094332d3Sopenharmony_ci        Json::Value setPath = GetValue(valueObj, "set.path");
170094332d3Sopenharmony_ci        if (isValidJsonString(getPath)) {
171094332d3Sopenharmony_ci            tempPowerSceneConfig.getPath = getPath.asString();
172094332d3Sopenharmony_ci            HDF_LOGI("getPath key=%{public}s", tempPowerSceneConfig.getPath.c_str());
173094332d3Sopenharmony_ci        }
174094332d3Sopenharmony_ci        if (isValidJsonString(setPath)) {
175094332d3Sopenharmony_ci            tempPowerSceneConfig.setPath = setPath.asString();
176094332d3Sopenharmony_ci            HDF_LOGI("setPath key=%{public}s", tempPowerSceneConfig.setPath.c_str());
177094332d3Sopenharmony_ci        }
178094332d3Sopenharmony_ci
179094332d3Sopenharmony_ci        sceneConfigMap_.insert(std::make_pair(key, tempPowerSceneConfig));
180094332d3Sopenharmony_ci    }
181094332d3Sopenharmony_ci    HDF_LOGI("The charge scene config size: %{public}d",
182094332d3Sopenharmony_ci        static_cast<int32_t>(sceneConfigMap_.size()));
183094332d3Sopenharmony_ci}
184094332d3Sopenharmony_ci
185094332d3Sopenharmony_cibool PowerConfig::isValidJsonString(const Json::Value& config) const
186094332d3Sopenharmony_ci{
187094332d3Sopenharmony_ci    return !config.isNull() && config.isString();
188094332d3Sopenharmony_ci}
189094332d3Sopenharmony_ci
190094332d3Sopenharmony_ci} // namespace V1_2
191094332d3Sopenharmony_ci} // namespace Power
192094332d3Sopenharmony_ci} // namespace HDI
193094332d3Sopenharmony_ci} // namespace OHOS