1 /*
2  * Copyright (c) 2023-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 "config_parser_base.h"
17 
18 #include <fstream>
19 #include <iostream>
20 #include <unistd.h>
21 
22 #include "display_log.h"
23 
24 namespace OHOS {
25 namespace DisplayPowerMgr {
26 namespace {
27 constexpr int DISPLAY_ID_MAX = 5;
28 constexpr uint16_t POINT_XY_SIZE = 2;
29 const std::string CONFIG_PATH_FOR_ROOT = "/sys_prod/etc/display/";
30 const std::string CONFIG_PATH_TYP = ".json";
31 const std::string CONFIG_PATHS[DISPLAY_ID_MAX] = {
32     "brightness_config/", // Unkonwn config, default path
33     "full/brightness_config/", // Full config
34     "brightness_config/", // Main config
35     "sub/brightness_config/", // Sub config
36     "brightness_config/", // Others config
37 };
38 } // namespace
39 
40 using namespace OHOS::DisplayPowerMgr;
41 
Get()42 ConfigParserBase& ConfigParserBase::Get()
43 {
44     static ConfigParserBase brightnessConfigParserBase;
45     return brightnessConfigParserBase;
46 }
47 
Initialize()48 void ConfigParserBase::Initialize()
49 {
50     std::lock_guard<std::mutex> lock(mLock);
51     if (mIsInitialized.load()) [[unlikely]]
52     {
53         DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Already init!");
54         return;
55     }
56     for (int displayId = 0; displayId < DISPLAY_ID_MAX; displayId++) {
57         DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] Already init!", displayId);
58         mConfigInfo[displayId] = ConfigInfo{};
59     }
60     mIsInitialized = true;
61 }
62 
GetDispIter(int displayId)63 std::unordered_map<int, ConfigParserBase::ConfigInfo>::iterator ConfigParserBase::GetDispIter(int displayId)
64 {
65     std::unordered_map<int, ConfigInfo>::iterator itDisp = mConfigInfo.find(displayId);
66     if (itDisp == mConfigInfo.end()) {
67         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
68     }
69     return itDisp;
70 }
71 
GetConstDispIter(int displayId) const72 std::unordered_map<int, ConfigParserBase::ConfigInfo>::const_iterator ConfigParserBase::GetConstDispIter(
73     int displayId) const
74 {
75     std::unordered_map<int, ConfigInfo>::const_iterator itDisp = mConfigInfo.find(displayId);
76     if (itDisp == mConfigInfo.end()) {
77         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
78     }
79     return itDisp;
80 }
81 
LoadConfigPath(int displayId,const std::string & configName) const82 const std::string ConfigParserBase::LoadConfigPath(int displayId, const std::string& configName) const
83 {
84     auto itDisp = GetConstDispIter(displayId);
85     std::string configPath{};
86     configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName);
87     // default path
88     if (itDisp == mConfigInfo.end()) {
89         configPath.append(CONFIG_PATH_TYP);
90         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
91         return configPath;
92     }
93 
94     // default path
95     const ConfigInfo& configInfo = itDisp->second;
96     if (configInfo.panelName.empty()) {
97         configPath.append(CONFIG_PATH_TYP);
98         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
99         return configPath;
100     }
101 
102     // name + version path
103     configPath.append("_").append(configInfo.panelName);
104     if (!configInfo.panelVersion.empty()) {
105         configPath = configPath.append("_").append(configInfo.panelVersion).append(CONFIG_PATH_TYP);
106         if (access(configPath.c_str(), R_OK) == 0) {
107             DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] name + version path [%{public}s]!",
108                 displayId, configPath.c_str());
109             return configPath;
110         }
111     }
112 
113     // version path
114     configPath.append(CONFIG_PATH_TYP);
115     if (access(configPath.c_str(), R_OK) == 0) {
116         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] version path [%{public}s]!", displayId, configPath.c_str());
117         return configPath;
118     }
119 
120     // default path
121     configPath.clear();
122     configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName).append(CONFIG_PATH_TYP);
123     DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
124     return configPath;
125 }
126 
LoadConfigRoot(int displayId,const std::string & configName) const127 const Json::Value ConfigParserBase::LoadConfigRoot(int displayId, const std::string& configName) const
128 {
129     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] LoadConfigRoot [%{public}s]!", displayId, configName.c_str());
130     const std::string configPath = LoadConfigPath(displayId, configName);
131     std::ifstream fileStream(configPath, std::ios::in | std::ios::binary);
132     if (!fileStream) {
133         DISPLAY_HILOGE(FEAT_BRIGHTNESS, "Open file %{public}s failure.", configName.c_str());
134         return Json::Value();
135     }
136     Json::Reader reader;
137     Json::Value root;
138     if (reader.parse(fileStream, root)) {
139         fileStream.close();
140         return root;
141     }
142     fileStream.close();
143     return Json::Value();
144 }
145 
ParsePointXy(const Json::Value & root,const std::string & name,std::vector<PointXy> & data) const146 void ConfigParserBase::ParsePointXy(
147     const Json::Value& root, const std::string& name, std::vector<PointXy>& data) const
148 {
149     data.clear();
150     if (!root[name.c_str()].isArray()) {
151         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found!", name.c_str());
152         return;
153     }
154     Json::Value array = root[name.c_str()];
155     for (auto value : array) {
156         if (!value.isArray()) {
157             DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> is not found!", name.c_str());
158             return;
159         }
160         PointXy pointXy{};
161         if (static_cast<uint32_t>(value.size()) != POINT_XY_SIZE) {
162             DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> size!=%{public}d!", name.c_str(), POINT_XY_SIZE);
163             return;
164         }
165         if (value[0].isNumeric()) {
166             pointXy.x = value[0].asFloat();
167         } else {
168             DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
169         }
170         if (value[1].isNumeric()) {
171             pointXy.y = value[1].asFloat();
172         } else {
173             DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
174         }
175         data.emplace_back(pointXy);
176     }
177 }
178 
PointXyToString(const std::string & name,const std::vector<PointXy> & data) const179 const std::string ConfigParserBase::PointXyToString(
180     const std::string& name, const std::vector<PointXy>& data) const
181 {
182     std::string text{};
183     text.append(name).append(": ");
184     for (auto value : data) {
185         text.append(std::to_string(value.x)).append(" ").append(std::to_string(value.y)).append(", ");
186     }
187     return text;
188 }
189 
190 
ParseScreenData(const Json::Value & root,const std::string & name,std::unordered_map<int,ScreenData> & data,const std::string paramName) const191 void ConfigParserBase::ParseScreenData(const Json::Value& root, const std::string& name,
192     std::unordered_map<int, ScreenData>& data, const std::string paramName) const
193 {
194     data.clear();
195     if (!root[name.c_str()].isArray()) {
196         DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found!", name.c_str());
197         return;
198     }
199     Json::Value array = root[name.c_str()];
200     for (auto value : array) {
201         ScreenData screenData{};
202         int displayMode = 0;
203         if (value[paramName].isNumeric()) {
204             displayMode = value[paramName].asInt();
205         }
206         if (value["displayId"].isNumeric()) {
207             screenData.displayId = value["displayId"].asInt();
208         }
209         if (value["sensorId"].isNumeric()) {
210             screenData.sensorId = value["sensorId"].asInt();
211         }
212         data[displayMode] = screenData;
213     }
214 }
215 
ScreenDataToString(const std::string & name,const std::unordered_map<int,ScreenData> & data,const std::string paramName) const216 const std::string ConfigParserBase::ScreenDataToString(const std::string& name,
217     const std::unordered_map<int, ScreenData>& data, const std::string paramName) const
218 {
219     std::string text{};
220     text.append(name).append(": ");
221     for (const auto& [key, value] : data) {
222         text.append(paramName).append(": ").append(std::to_string(key)).append(" ");
223         text.append("displayId").append(": ").append(std::to_string(value.displayId)).append(" ");
224         text.append("sensorId").append(": ").append(std::to_string(value.sensorId)).append(" ");
225     }
226     return text;
227 }
228 } // namespace DisplayPowerMgr
229 } // namespace OHOS
230