1595d5899Sopenharmony_ci/*
2595d5899Sopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3595d5899Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4595d5899Sopenharmony_ci * you may not use this file except in compliance with the License.
5595d5899Sopenharmony_ci * You may obtain a copy of the License at
6595d5899Sopenharmony_ci *
7595d5899Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8595d5899Sopenharmony_ci *
9595d5899Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10595d5899Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11595d5899Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12595d5899Sopenharmony_ci * See the License for the specific language governing permissions and
13595d5899Sopenharmony_ci * limitations under the License.
14595d5899Sopenharmony_ci */
15595d5899Sopenharmony_ci
16595d5899Sopenharmony_ci#include "config_parser_base.h"
17595d5899Sopenharmony_ci
18595d5899Sopenharmony_ci#include <fstream>
19595d5899Sopenharmony_ci#include <iostream>
20595d5899Sopenharmony_ci#include <unistd.h>
21595d5899Sopenharmony_ci
22595d5899Sopenharmony_ci#include "display_log.h"
23595d5899Sopenharmony_ci
24595d5899Sopenharmony_cinamespace OHOS {
25595d5899Sopenharmony_cinamespace DisplayPowerMgr {
26595d5899Sopenharmony_cinamespace {
27595d5899Sopenharmony_ciconstexpr int DISPLAY_ID_MAX = 5;
28595d5899Sopenharmony_ciconstexpr uint16_t POINT_XY_SIZE = 2;
29595d5899Sopenharmony_ciconst std::string CONFIG_PATH_FOR_ROOT = "/sys_prod/etc/display/";
30595d5899Sopenharmony_ciconst std::string CONFIG_PATH_TYP = ".json";
31595d5899Sopenharmony_ciconst std::string CONFIG_PATHS[DISPLAY_ID_MAX] = {
32595d5899Sopenharmony_ci    "brightness_config/", // Unkonwn config, default path
33595d5899Sopenharmony_ci    "full/brightness_config/", // Full config
34595d5899Sopenharmony_ci    "brightness_config/", // Main config
35595d5899Sopenharmony_ci    "sub/brightness_config/", // Sub config
36595d5899Sopenharmony_ci    "brightness_config/", // Others config
37595d5899Sopenharmony_ci};
38595d5899Sopenharmony_ci} // namespace
39595d5899Sopenharmony_ci
40595d5899Sopenharmony_ciusing namespace OHOS::DisplayPowerMgr;
41595d5899Sopenharmony_ci
42595d5899Sopenharmony_ciConfigParserBase& ConfigParserBase::Get()
43595d5899Sopenharmony_ci{
44595d5899Sopenharmony_ci    static ConfigParserBase brightnessConfigParserBase;
45595d5899Sopenharmony_ci    return brightnessConfigParserBase;
46595d5899Sopenharmony_ci}
47595d5899Sopenharmony_ci
48595d5899Sopenharmony_civoid ConfigParserBase::Initialize()
49595d5899Sopenharmony_ci{
50595d5899Sopenharmony_ci    std::lock_guard<std::mutex> lock(mLock);
51595d5899Sopenharmony_ci    if (mIsInitialized.load()) [[unlikely]]
52595d5899Sopenharmony_ci    {
53595d5899Sopenharmony_ci        DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Already init!");
54595d5899Sopenharmony_ci        return;
55595d5899Sopenharmony_ci    }
56595d5899Sopenharmony_ci    for (int displayId = 0; displayId < DISPLAY_ID_MAX; displayId++) {
57595d5899Sopenharmony_ci        DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] Already init!", displayId);
58595d5899Sopenharmony_ci        mConfigInfo[displayId] = ConfigInfo{};
59595d5899Sopenharmony_ci    }
60595d5899Sopenharmony_ci    mIsInitialized = true;
61595d5899Sopenharmony_ci}
62595d5899Sopenharmony_ci
63595d5899Sopenharmony_cistd::unordered_map<int, ConfigParserBase::ConfigInfo>::iterator ConfigParserBase::GetDispIter(int displayId)
64595d5899Sopenharmony_ci{
65595d5899Sopenharmony_ci    std::unordered_map<int, ConfigInfo>::iterator itDisp = mConfigInfo.find(displayId);
66595d5899Sopenharmony_ci    if (itDisp == mConfigInfo.end()) {
67595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
68595d5899Sopenharmony_ci    }
69595d5899Sopenharmony_ci    return itDisp;
70595d5899Sopenharmony_ci}
71595d5899Sopenharmony_ci
72595d5899Sopenharmony_cistd::unordered_map<int, ConfigParserBase::ConfigInfo>::const_iterator ConfigParserBase::GetConstDispIter(
73595d5899Sopenharmony_ci    int displayId) const
74595d5899Sopenharmony_ci{
75595d5899Sopenharmony_ci    std::unordered_map<int, ConfigInfo>::const_iterator itDisp = mConfigInfo.find(displayId);
76595d5899Sopenharmony_ci    if (itDisp == mConfigInfo.end()) {
77595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
78595d5899Sopenharmony_ci    }
79595d5899Sopenharmony_ci    return itDisp;
80595d5899Sopenharmony_ci}
81595d5899Sopenharmony_ci
82595d5899Sopenharmony_ciconst std::string ConfigParserBase::LoadConfigPath(int displayId, const std::string& configName) const
83595d5899Sopenharmony_ci{
84595d5899Sopenharmony_ci    auto itDisp = GetConstDispIter(displayId);
85595d5899Sopenharmony_ci    std::string configPath{};
86595d5899Sopenharmony_ci    configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName);
87595d5899Sopenharmony_ci    // default path
88595d5899Sopenharmony_ci    if (itDisp == mConfigInfo.end()) {
89595d5899Sopenharmony_ci        configPath.append(CONFIG_PATH_TYP);
90595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
91595d5899Sopenharmony_ci        return configPath;
92595d5899Sopenharmony_ci    }
93595d5899Sopenharmony_ci
94595d5899Sopenharmony_ci    // default path
95595d5899Sopenharmony_ci    const ConfigInfo& configInfo = itDisp->second;
96595d5899Sopenharmony_ci    if (configInfo.panelName.empty()) {
97595d5899Sopenharmony_ci        configPath.append(CONFIG_PATH_TYP);
98595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
99595d5899Sopenharmony_ci        return configPath;
100595d5899Sopenharmony_ci    }
101595d5899Sopenharmony_ci
102595d5899Sopenharmony_ci    // name + version path
103595d5899Sopenharmony_ci    configPath.append("_").append(configInfo.panelName);
104595d5899Sopenharmony_ci    if (!configInfo.panelVersion.empty()) {
105595d5899Sopenharmony_ci        configPath = configPath.append("_").append(configInfo.panelVersion).append(CONFIG_PATH_TYP);
106595d5899Sopenharmony_ci        if (access(configPath.c_str(), R_OK) == 0) {
107595d5899Sopenharmony_ci            DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] name + version path [%{public}s]!",
108595d5899Sopenharmony_ci                displayId, configPath.c_str());
109595d5899Sopenharmony_ci            return configPath;
110595d5899Sopenharmony_ci        }
111595d5899Sopenharmony_ci    }
112595d5899Sopenharmony_ci
113595d5899Sopenharmony_ci    // version path
114595d5899Sopenharmony_ci    configPath.append(CONFIG_PATH_TYP);
115595d5899Sopenharmony_ci    if (access(configPath.c_str(), R_OK) == 0) {
116595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] version path [%{public}s]!", displayId, configPath.c_str());
117595d5899Sopenharmony_ci        return configPath;
118595d5899Sopenharmony_ci    }
119595d5899Sopenharmony_ci
120595d5899Sopenharmony_ci    // default path
121595d5899Sopenharmony_ci    configPath.clear();
122595d5899Sopenharmony_ci    configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName).append(CONFIG_PATH_TYP);
123595d5899Sopenharmony_ci    DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
124595d5899Sopenharmony_ci    return configPath;
125595d5899Sopenharmony_ci}
126595d5899Sopenharmony_ci
127595d5899Sopenharmony_ciconst Json::Value ConfigParserBase::LoadConfigRoot(int displayId, const std::string& configName) const
128595d5899Sopenharmony_ci{
129595d5899Sopenharmony_ci    DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] LoadConfigRoot [%{public}s]!", displayId, configName.c_str());
130595d5899Sopenharmony_ci    const std::string configPath = LoadConfigPath(displayId, configName);
131595d5899Sopenharmony_ci    std::ifstream fileStream(configPath, std::ios::in | std::ios::binary);
132595d5899Sopenharmony_ci    if (!fileStream) {
133595d5899Sopenharmony_ci        DISPLAY_HILOGE(FEAT_BRIGHTNESS, "Open file %{public}s failure.", configName.c_str());
134595d5899Sopenharmony_ci        return Json::Value();
135595d5899Sopenharmony_ci    }
136595d5899Sopenharmony_ci    Json::Reader reader;
137595d5899Sopenharmony_ci    Json::Value root;
138595d5899Sopenharmony_ci    if (reader.parse(fileStream, root)) {
139595d5899Sopenharmony_ci        fileStream.close();
140595d5899Sopenharmony_ci        return root;
141595d5899Sopenharmony_ci    }
142595d5899Sopenharmony_ci    fileStream.close();
143595d5899Sopenharmony_ci    return Json::Value();
144595d5899Sopenharmony_ci}
145595d5899Sopenharmony_ci
146595d5899Sopenharmony_civoid ConfigParserBase::ParsePointXy(
147595d5899Sopenharmony_ci    const Json::Value& root, const std::string& name, std::vector<PointXy>& data) const
148595d5899Sopenharmony_ci{
149595d5899Sopenharmony_ci    data.clear();
150595d5899Sopenharmony_ci    if (!root[name.c_str()].isArray()) {
151595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found!", name.c_str());
152595d5899Sopenharmony_ci        return;
153595d5899Sopenharmony_ci    }
154595d5899Sopenharmony_ci    Json::Value array = root[name.c_str()];
155595d5899Sopenharmony_ci    for (auto value : array) {
156595d5899Sopenharmony_ci        if (!value.isArray()) {
157595d5899Sopenharmony_ci            DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> is not found!", name.c_str());
158595d5899Sopenharmony_ci            return;
159595d5899Sopenharmony_ci        }
160595d5899Sopenharmony_ci        PointXy pointXy{};
161595d5899Sopenharmony_ci        if (static_cast<uint32_t>(value.size()) != POINT_XY_SIZE) {
162595d5899Sopenharmony_ci            DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> size!=%{public}d!", name.c_str(), POINT_XY_SIZE);
163595d5899Sopenharmony_ci            return;
164595d5899Sopenharmony_ci        }
165595d5899Sopenharmony_ci        if (value[0].isNumeric()) {
166595d5899Sopenharmony_ci            pointXy.x = value[0].asFloat();
167595d5899Sopenharmony_ci        } else {
168595d5899Sopenharmony_ci            DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
169595d5899Sopenharmony_ci        }
170595d5899Sopenharmony_ci        if (value[1].isNumeric()) {
171595d5899Sopenharmony_ci            pointXy.y = value[1].asFloat();
172595d5899Sopenharmony_ci        } else {
173595d5899Sopenharmony_ci            DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
174595d5899Sopenharmony_ci        }
175595d5899Sopenharmony_ci        data.emplace_back(pointXy);
176595d5899Sopenharmony_ci    }
177595d5899Sopenharmony_ci}
178595d5899Sopenharmony_ci
179595d5899Sopenharmony_ciconst std::string ConfigParserBase::PointXyToString(
180595d5899Sopenharmony_ci    const std::string& name, const std::vector<PointXy>& data) const
181595d5899Sopenharmony_ci{
182595d5899Sopenharmony_ci    std::string text{};
183595d5899Sopenharmony_ci    text.append(name).append(": ");
184595d5899Sopenharmony_ci    for (auto value : data) {
185595d5899Sopenharmony_ci        text.append(std::to_string(value.x)).append(" ").append(std::to_string(value.y)).append(", ");
186595d5899Sopenharmony_ci    }
187595d5899Sopenharmony_ci    return text;
188595d5899Sopenharmony_ci}
189595d5899Sopenharmony_ci
190595d5899Sopenharmony_ci
191595d5899Sopenharmony_civoid ConfigParserBase::ParseScreenData(const Json::Value& root, const std::string& name,
192595d5899Sopenharmony_ci    std::unordered_map<int, ScreenData>& data, const std::string paramName) const
193595d5899Sopenharmony_ci{
194595d5899Sopenharmony_ci    data.clear();
195595d5899Sopenharmony_ci    if (!root[name.c_str()].isArray()) {
196595d5899Sopenharmony_ci        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found!", name.c_str());
197595d5899Sopenharmony_ci        return;
198595d5899Sopenharmony_ci    }
199595d5899Sopenharmony_ci    Json::Value array = root[name.c_str()];
200595d5899Sopenharmony_ci    for (auto value : array) {
201595d5899Sopenharmony_ci        ScreenData screenData{};
202595d5899Sopenharmony_ci        int displayMode = 0;
203595d5899Sopenharmony_ci        if (value[paramName].isNumeric()) {
204595d5899Sopenharmony_ci            displayMode = value[paramName].asInt();
205595d5899Sopenharmony_ci        }
206595d5899Sopenharmony_ci        if (value["displayId"].isNumeric()) {
207595d5899Sopenharmony_ci            screenData.displayId = value["displayId"].asInt();
208595d5899Sopenharmony_ci        }
209595d5899Sopenharmony_ci        if (value["sensorId"].isNumeric()) {
210595d5899Sopenharmony_ci            screenData.sensorId = value["sensorId"].asInt();
211595d5899Sopenharmony_ci        }
212595d5899Sopenharmony_ci        data[displayMode] = screenData;
213595d5899Sopenharmony_ci    }
214595d5899Sopenharmony_ci}
215595d5899Sopenharmony_ci
216595d5899Sopenharmony_ciconst std::string ConfigParserBase::ScreenDataToString(const std::string& name,
217595d5899Sopenharmony_ci    const std::unordered_map<int, ScreenData>& data, const std::string paramName) const
218595d5899Sopenharmony_ci{
219595d5899Sopenharmony_ci    std::string text{};
220595d5899Sopenharmony_ci    text.append(name).append(": ");
221595d5899Sopenharmony_ci    for (const auto& [key, value] : data) {
222595d5899Sopenharmony_ci        text.append(paramName).append(": ").append(std::to_string(key)).append(" ");
223595d5899Sopenharmony_ci        text.append("displayId").append(": ").append(std::to_string(value.displayId)).append(" ");
224595d5899Sopenharmony_ci        text.append("sensorId").append(": ").append(std::to_string(value.sensorId)).append(" ");
225595d5899Sopenharmony_ci    }
226595d5899Sopenharmony_ci    return text;
227595d5899Sopenharmony_ci}
228595d5899Sopenharmony_ci} // namespace DisplayPowerMgr
229595d5899Sopenharmony_ci} // namespace OHOS
230