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 constexpr int POINT_X_INDEX = 0;
30 constexpr int POINT_Y_INDEX = 1;
31 const std::string CONFIG_PATH_FOR_ROOT = "/sys_prod/etc/display/";
32 const std::string CONFIG_PATH_TYP = ".json";
33 const std::string CONFIG_PATHS[DISPLAY_ID_MAX] = {
34 "brightness_config/", // Unkonwn config, default path
35 "full/brightness_config/", // Full config
36 "brightness_config/", // Main config
37 "sub/brightness_config/", // Sub config
38 "brightness_config/", // Others config
39 };
40 } // namespace
41
42 using namespace OHOS::DisplayPowerMgr;
43
Get()44 ConfigParserBase& ConfigParserBase::Get()
45 {
46 static ConfigParserBase brightnessConfigParserBase;
47 return brightnessConfigParserBase;
48 }
49
Initialize()50 void ConfigParserBase::Initialize()
51 {
52 std::lock_guard<std::mutex> lock(mLock);
53 if (mIsInitialized.load()) [[unlikely]]
54 {
55 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Already init!");
56 return;
57 }
58 for (int displayId = 0; displayId < DISPLAY_ID_MAX; displayId++) {
59 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] Already init!", displayId);
60 mConfigInfo[displayId] = ConfigInfo{};
61 }
62 mIsInitialized = true;
63 }
64
GetDispIter(int displayId)65 std::unordered_map<int, ConfigParserBase::ConfigInfo>::iterator ConfigParserBase::GetDispIter(int displayId)
66 {
67 std::unordered_map<int, ConfigInfo>::iterator itDisp = mConfigInfo.find(displayId);
68 if (itDisp == mConfigInfo.end()) {
69 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
70 }
71 return itDisp;
72 }
73
GetConstDispIter(int displayId) const74 std::unordered_map<int, ConfigParserBase::ConfigInfo>::const_iterator ConfigParserBase::GetConstDispIter(
75 int displayId) const
76 {
77 std::unordered_map<int, ConfigInfo>::const_iterator itDisp = mConfigInfo.find(displayId);
78 if (itDisp == mConfigInfo.end()) {
79 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d]Failed to find config", displayId);
80 }
81 return itDisp;
82 }
83
LoadConfigPath(int displayId,const std::string & configName) const84 const std::string ConfigParserBase::LoadConfigPath(int displayId, const std::string& configName) const
85 {
86 auto itDisp = GetConstDispIter(displayId);
87 std::string configPath{};
88 configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName);
89 // default path
90 if (itDisp == mConfigInfo.end()) {
91 configPath.append(CONFIG_PATH_TYP);
92 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
93 return configPath;
94 }
95
96 // default path
97 const ConfigInfo& configInfo = itDisp->second;
98 if (configInfo.panelName.empty()) {
99 configPath.append(CONFIG_PATH_TYP);
100 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
101 return configPath;
102 }
103
104 // name + version path
105 configPath.append("_").append(configInfo.panelName);
106 if (!configInfo.panelVersion.empty()) {
107 configPath = configPath.append("_").append(configInfo.panelVersion).append(CONFIG_PATH_TYP);
108 if (access(configPath.c_str(), R_OK) == 0) {
109 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] name + version path [%{public}s]!",
110 displayId, configPath.c_str());
111 return configPath;
112 }
113 }
114
115 // version path
116 configPath.append(CONFIG_PATH_TYP);
117 if (access(configPath.c_str(), R_OK) == 0) {
118 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] version path [%{public}s]!", displayId, configPath.c_str());
119 return configPath;
120 }
121
122 // default path
123 configPath.clear();
124 configPath.append(CONFIG_PATH_FOR_ROOT).append(CONFIG_PATHS[displayId]).append(configName).append(CONFIG_PATH_TYP);
125 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "[%{public}d] default path [%{public}s]!", displayId, configPath.c_str());
126 return configPath;
127 }
128
LoadConfigRoot(int displayId,const std::string & configName) const129 const std::string ConfigParserBase::LoadConfigRoot(int displayId, const std::string& configName) const
130 {
131 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[%{public}d] LoadConfigRoot [%{public}s]!", displayId, configName.c_str());
132 const std::string configPath = LoadConfigPath(displayId, configName);
133 std::ifstream fileStream(configPath, std::ios::in | std::ios::binary);
134 if (!fileStream) {
135 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "Open file %{public}s failure.", configName.c_str());
136 return std::string("");
137 }
138
139 std::string fileContent((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
140 fileStream.close();
141 return fileContent;
142 }
143
ParsePointXy(const cJSON * root,const std::string & name,std::vector<PointXy> & data) const144 void ConfigParserBase::ParsePointXy(
145 const cJSON* root, const std::string& name, std::vector<PointXy>& data) const
146 {
147 data.clear();
148 const cJSON* array = cJSON_GetObjectItemCaseSensitive(root, name.c_str());
149 if (!DisplayJsonUtils::IsValidJsonArray(array)) {
150 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found or is not an array!", name.c_str());
151 return;
152 }
153
154 cJSON* item = nullptr;
155 cJSON_ArrayForEach(item, array) {
156 if (!DisplayJsonUtils::IsValidJsonArray(item)) {
157 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> element is not an array!", name.c_str());
158 return;
159 }
160
161 PointXy pointXy{};
162 uint32_t arraySize = (uint32_t)cJSON_GetArraySize(item);
163 if (arraySize != POINT_XY_SIZE) {
164 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "array <%{public}s> size!=%{public}d!", name.c_str(), POINT_XY_SIZE);
165 return;
166 }
167
168 const cJSON* xNode = cJSON_GetArrayItem(item, POINT_X_INDEX);
169 if (DisplayJsonUtils::IsValidJsonNumber(xNode)) {
170 pointXy.x = static_cast<float>(xNode->valuedouble);
171 } else {
172 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
173 }
174
175 const cJSON* yNode = cJSON_GetArrayItem(item, POINT_Y_INDEX);
176 if (DisplayJsonUtils::IsValidJsonNumber(yNode)) {
177 pointXy.y = static_cast<float>(yNode->valuedouble);
178 } else {
179 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "parse [%{public}s] error!", name.c_str());
180 }
181
182 data.emplace_back(pointXy);
183 }
184 }
185
PointXyToString(const std::string & name,const std::vector<PointXy> & data) const186 const std::string ConfigParserBase::PointXyToString(
187 const std::string& name, const std::vector<PointXy>& data) const
188 {
189 std::string text{};
190 text.append(name).append(": ");
191 for (auto value : data) {
192 text.append(std::to_string(value.x)).append(" ").append(std::to_string(value.y)).append(", ");
193 }
194 return text;
195 }
196
197
ParseScreenData(const cJSON * root,const std::string & name,std::unordered_map<int,ScreenData> & data,const std::string paramName) const198 void ConfigParserBase::ParseScreenData(const cJSON* root, const std::string& name,
199 std::unordered_map<int, ScreenData>& data, const std::string paramName) const
200 {
201 data.clear();
202 const cJSON* array = cJSON_GetObjectItemCaseSensitive(root, name.c_str());
203 if (!DisplayJsonUtils::IsValidJsonArray(array)) {
204 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "root <%{public}s> is not found or is not an array!", name.c_str());
205 return;
206 }
207
208 cJSON* item = nullptr;
209 cJSON_ArrayForEach(item, array) {
210 if (!cJSON_IsObject(item)) {
211 continue;
212 }
213 ScreenData screenData{};
214 int displayMode = 0;
215 const cJSON* displayModeNode = cJSON_GetObjectItemCaseSensitive(item, paramName.c_str());
216 if (DisplayJsonUtils::IsValidJsonNumber(displayModeNode)) {
217 displayMode = displayModeNode->valueint;
218 }
219
220 const cJSON* displayIdNode = cJSON_GetObjectItemCaseSensitive(item, "displayId");
221 if (DisplayJsonUtils::IsValidJsonNumber(displayIdNode)) {
222 screenData.displayId = displayIdNode->valueint;
223 }
224
225 const cJSON* sensorIdNode = cJSON_GetObjectItemCaseSensitive(item, "sensorId");
226 if (DisplayJsonUtils::IsValidJsonNumber(sensorIdNode)) {
227 screenData.sensorId = sensorIdNode->valueint;
228 }
229
230 data[displayMode] = screenData;
231 }
232 }
233
ScreenDataToString(const std::string & name,const std::unordered_map<int,ScreenData> & data,const std::string paramName) const234 const std::string ConfigParserBase::ScreenDataToString(const std::string& name,
235 const std::unordered_map<int, ScreenData>& data, const std::string paramName) const
236 {
237 std::string text{};
238 text.append(name).append(": ");
239 for (const auto& [key, value] : data) {
240 text.append(paramName).append(": ").append(std::to_string(key)).append(" ");
241 text.append("displayId").append(": ").append(std::to_string(value.displayId)).append(" ");
242 text.append("sensorId").append(": ").append(std::to_string(value.sensorId)).append(" ");
243 }
244 return text;
245 }
246 } // namespace DisplayPowerMgr
247 } // namespace OHOS
248