1 /*
2 * Copyright (c) 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 #include "screen_scene_config.h"
16
17 #include <climits>
18 #include <cstdint>
19 #include <cstdlib>
20 #include <libxml/globals.h>
21 #include <libxml/xmlstring.h>
22 #include <map>
23 #include <string>
24 #include <utility>
25 #include <vector>
26
27 #include "config_policy_utils.h"
28 #include "include/core/SkMatrix.h"
29 #include "include/core/SkPath.h"
30 #include "include/core/SkPathMeasure.h"
31 #include "include/utils/SkParsePath.h"
32 #include "window_manager_hilog.h"
33
34 namespace OHOS::Rosen {
35 namespace {
36 constexpr uint32_t NO_WATERFALL_DISPLAY_COMPRESSION_SIZE = 0;
37 constexpr uint32_t DISPLAY_PHYSICAL_SIZE = 2;
38 enum XmlNodeElement {
39 DPI = 0,
40 SUB_DPI,
41 IS_WATERFALL_DISPLAY,
42 CURVED_SCREEN_BOUNDARY,
43 CURVED_AREA_IN_LANDSCAPE,
44 IS_CURVED_COMPRESS_ENABLED,
45 BUILD_IN_DEFAULT_ORIENTATION,
46 DEFAULT_DEVICE_ROTATION_OFFSET,
47 DEFAULT_DISPLAY_CUTOUT_PATH,
48 SUB_DISPLAY_CUTOUT_PATH,
49 HALL_SWITCH_APP,
50 PACKAGE_NAME,
51 ROTATION_POLICY,
52 SCREEN_SNAPSHOT_BUNDLE_NAME,
53 SCREEN_SNAPSHOT_ABILITY_NAME,
54 IS_RIGHT_POWER_BUTTON,
55 SUPPORT_ROTATE_WITH_SCREEN,
56 EXTERNAL_SCREEN_DEFAULT_MODE,
57 CAST_BUNDLE_NAME,
58 CAST_ABILITY_NAME,
59 PHYSICAL_DISPLAY_RESOLUTION
60 };
61 }
62
63 std::map<std::string, bool> ScreenSceneConfig::enableConfig_;
64 std::map<std::string, std::vector<int>> ScreenSceneConfig::intNumbersConfig_;
65 std::map<std::string, std::string> ScreenSceneConfig::stringConfig_;
66 std::map<std::string, std::vector<std::string>> ScreenSceneConfig::stringListConfig_;
67 std::map<uint64_t, std::vector<DMRect>> ScreenSceneConfig::cutoutBoundaryRectMap_;
68 std::vector<DisplayPhysicalResolution> ScreenSceneConfig::displayPhysicalResolution_;
69 std::vector<DMRect> ScreenSceneConfig::subCutoutBoundaryRect_;
70 bool ScreenSceneConfig::isWaterfallDisplay_ = false;
71 bool ScreenSceneConfig::isScreenCompressionEnableInLandscape_ = false;
72 uint32_t ScreenSceneConfig::curvedAreaInLandscape_ = 0;
73 std::map<int32_t, std::string> ScreenSceneConfig::xmlNodeMap_ = {
74 {DPI, "dpi"},
75 {SUB_DPI, "subDpi"},
76 {IS_WATERFALL_DISPLAY, "isWaterfallDisplay"},
77 {CURVED_SCREEN_BOUNDARY, "curvedScreenBoundary"},
78 {CURVED_AREA_IN_LANDSCAPE, "waterfallAreaCompressionSizeWhenHorzontal"},
79 {IS_CURVED_COMPRESS_ENABLED, "isWaterfallAreaCompressionEnableWhenHorizontal"},
80 {BUILD_IN_DEFAULT_ORIENTATION, "buildInDefaultOrientation"},
81 {DEFAULT_DEVICE_ROTATION_OFFSET, "defaultDeviceRotationOffset"},
82 {DEFAULT_DISPLAY_CUTOUT_PATH, "defaultDisplayCutoutPath"},
83 {SUB_DISPLAY_CUTOUT_PATH, "subDisplayCutoutPath"},
84 {HALL_SWITCH_APP, "hallSwitchApp"},
85 {PACKAGE_NAME, "packageName"},
86 {ROTATION_POLICY, "rotationPolicy"},
87 {SCREEN_SNAPSHOT_BUNDLE_NAME, "screenSnapshotBundleName"},
88 {SCREEN_SNAPSHOT_ABILITY_NAME, "screenSnapshotAbilityName"},
89 {IS_RIGHT_POWER_BUTTON, "isRightPowerButton"},
90 {SUPPORT_ROTATE_WITH_SCREEN, "supportRotateWithSensor"},
91 {EXTERNAL_SCREEN_DEFAULT_MODE, "externalScreenDefaultMode"},
92 {CAST_BUNDLE_NAME, "castBundleName"},
93 {CAST_ABILITY_NAME, "castAbilityName"},
94 {PHYSICAL_DISPLAY_RESOLUTION, "physicalDisplayResolution"}
95 };
96
97
Split(std::string str,std::string pattern)98 std::vector<std::string> ScreenSceneConfig::Split(std::string str, std::string pattern)
99 {
100 std::vector<std::string> result;
101 str += pattern;
102 int32_t length = static_cast<int32_t>(str.size());
103 for (int32_t i = 0; i < length; i++) {
104 int32_t position = static_cast<int32_t>(str.find(pattern, i));
105 if (position < length) {
106 std::string tmp = str.substr(i, position - i);
107 result.push_back(tmp);
108 i = position + static_cast<int32_t>(pattern.size()) - 1;
109 }
110 }
111 return result;
112 }
113
IsNumber(std::string str)114 bool ScreenSceneConfig::IsNumber(std::string str)
115 {
116 if (str.size() == 0) {
117 return false;
118 }
119 for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) {
120 if (str.at(i) < '0' || str.at(i) > '9') {
121 return false;
122 }
123 }
124 return true;
125 }
126
GetConfigPath(const std::string & configFileName)127 std::string ScreenSceneConfig::GetConfigPath(const std::string& configFileName)
128 {
129 char buf[PATH_MAX + 1];
130 char* configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX + 1);
131 char tmpPath[PATH_MAX + 1] = { 0 };
132 if (!configPath || strlen(configPath) == 0 || strlen(configPath) > PATH_MAX || !realpath(configPath, tmpPath)) {
133 TLOGI(WmsLogTag::DMS, "[SsConfig] can not get customization config file");
134 return "/system/" + configFileName;
135 }
136 return std::string(tmpPath);
137 }
138
LoadConfigXml()139 bool ScreenSceneConfig::LoadConfigXml()
140 {
141 auto configFilePath = GetConfigPath("etc/window/resources/display_manager_config.xml");
142 xmlDocPtr docPtr = nullptr;
143 {
144 std::lock_guard<std::recursive_mutex> lock(mutex_);
145 docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS);
146 }
147 TLOGI(WmsLogTag::DMS, "[SsConfig] filePath: %{public}s", configFilePath.c_str());
148 if (docPtr == nullptr) {
149 TLOGE(WmsLogTag::DMS, "[SsConfig] load xml error!");
150 return false;
151 }
152 xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
153 if (rootPtr == nullptr || rootPtr->name == nullptr ||
154 xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
155 TLOGE(WmsLogTag::DMS, "[SsConfig] get root element failed!");
156 xmlFreeDoc(docPtr);
157 return false;
158 }
159 for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
160 if (!IsValidNode(*curNodePtr)) {
161 TLOGE(WmsLogTag::DMS, "SsConfig]: invalid node!");
162 continue;
163 }
164 ParseNodeConfig(curNodePtr);
165 }
166 xmlFreeDoc(docPtr);
167 return true;
168 }
169
ParseNodeConfig(const xmlNodePtr & currNode)170 void ScreenSceneConfig::ParseNodeConfig(const xmlNodePtr& currNode)
171 {
172 std::string nodeName(reinterpret_cast<const char*>(currNode->name));
173 bool enableConfigCheck = (xmlNodeMap_[IS_WATERFALL_DISPLAY] == nodeName) ||
174 (xmlNodeMap_[IS_CURVED_COMPRESS_ENABLED] == nodeName) ||
175 (xmlNodeMap_[IS_RIGHT_POWER_BUTTON] == nodeName) ||
176 (xmlNodeMap_[SUPPORT_ROTATE_WITH_SCREEN] == nodeName);
177 bool numberConfigCheck = (xmlNodeMap_[DPI] == nodeName) ||
178 (xmlNodeMap_[SUB_DPI] == nodeName) ||
179 (xmlNodeMap_[CURVED_SCREEN_BOUNDARY] == nodeName) ||
180 (xmlNodeMap_[CURVED_AREA_IN_LANDSCAPE] == nodeName) ||
181 (xmlNodeMap_[BUILD_IN_DEFAULT_ORIENTATION] == nodeName) ||
182 (xmlNodeMap_[DEFAULT_DEVICE_ROTATION_OFFSET] == nodeName);
183 bool stringConfigCheck = (xmlNodeMap_[DEFAULT_DISPLAY_CUTOUT_PATH] == nodeName) ||
184 (xmlNodeMap_[SUB_DISPLAY_CUTOUT_PATH] == nodeName) ||
185 (xmlNodeMap_[ROTATION_POLICY] == nodeName) ||
186 (xmlNodeMap_[SCREEN_SNAPSHOT_BUNDLE_NAME] == nodeName) ||
187 (xmlNodeMap_[SCREEN_SNAPSHOT_ABILITY_NAME] == nodeName) ||
188 (xmlNodeMap_[EXTERNAL_SCREEN_DEFAULT_MODE] == nodeName) ||
189 (xmlNodeMap_[CAST_BUNDLE_NAME] == nodeName) ||
190 (xmlNodeMap_[CAST_ABILITY_NAME] == nodeName);
191 if (enableConfigCheck) {
192 ReadEnableConfigInfo(currNode);
193 } else if (numberConfigCheck) {
194 ReadIntNumbersConfigInfo(currNode);
195 } else if (stringConfigCheck) {
196 ReadStringConfigInfo(currNode);
197 } else if (xmlNodeMap_[HALL_SWITCH_APP] == nodeName) {
198 ReadStringListConfigInfo(currNode, nodeName);
199 } else if (xmlNodeMap_[PHYSICAL_DISPLAY_RESOLUTION] == nodeName) {
200 ReadPhysicalDisplayConfigInfo(currNode);
201 } else {
202 TLOGI(WmsLogTag::DMS, "xml config node name is not match, nodeName:%{public}s", nodeName.c_str());
203 }
204 }
205
IsValidNode(const xmlNode & currNode)206 bool ScreenSceneConfig::IsValidNode(const xmlNode& currNode)
207 {
208 if (currNode.name == nullptr || currNode.type == XML_COMMENT_NODE) {
209 return false;
210 }
211 return true;
212 }
213
ReadIntNumbersConfigInfo(const xmlNodePtr & currNode)214 void ScreenSceneConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode)
215 {
216 xmlChar* context = xmlNodeGetContent(currNode);
217 if (context == nullptr) {
218 TLOGE(WmsLogTag::DMS, "[SsConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
219 return;
220 }
221
222 std::vector<int> numbersVec;
223 std::string numbersStr = reinterpret_cast<const char*>(context);
224 if (numbersStr.empty()) {
225 xmlFree(context);
226 return;
227 }
228 auto numbers = Split(numbersStr, " ");
229 for (auto& num : numbers) {
230 if (!IsNumber(num)) {
231 TLOGE(WmsLogTag::DMS, "[SsConfig] read number error: nodeName:(%{public}s)", currNode->name);
232 xmlFree(context);
233 return;
234 }
235 numbersVec.emplace_back(std::stoi(num));
236 }
237
238 std::string nodeName = reinterpret_cast<const char *>(currNode->name);
239 intNumbersConfig_[nodeName] = numbersVec;
240 xmlFree(context);
241 }
242
ReadPhysicalDisplayConfigInfo(const xmlNodePtr & currNode)243 void ScreenSceneConfig::ReadPhysicalDisplayConfigInfo(const xmlNodePtr& currNode)
244 {
245 xmlChar* displayMode = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("displayMode"));
246 if (displayMode == nullptr) {
247 TLOGE(WmsLogTag::DMS, "[SsConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
248 return;
249 }
250 xmlChar* displayModeContext = xmlNodeGetContent(currNode);
251 if (displayModeContext == nullptr) {
252 TLOGE(WmsLogTag::DMS, "[SsConfig] read xml nodeName:(%{public}s) context null", currNode->name);
253 xmlFree(displayMode);
254 return;
255 }
256 std::string displaySizeStr = reinterpret_cast<const char*>(displayModeContext);
257 if (displaySizeStr.empty()) {
258 xmlFree(displayModeContext);
259 xmlFree(displayMode);
260 return;
261 }
262 auto displaySizeArray = Split(displaySizeStr, ":");
263 if (displaySizeArray.size() != DISPLAY_PHYSICAL_SIZE) {
264 xmlFree(displayModeContext);
265 xmlFree(displayMode);
266 return;
267 }
268 DisplayPhysicalResolution physicalSize;
269 if (!xmlStrcmp(displayMode, reinterpret_cast<const xmlChar*>("FOLD_DISPLAY_MODE_FULL"))) {
270 physicalSize.foldDisplayMode_ = FoldDisplayMode::FULL;
271 } else if (!xmlStrcmp(displayMode, reinterpret_cast<const xmlChar*>("FOLD_DISPLAY_MODE_MAIN"))) {
272 physicalSize.foldDisplayMode_ = FoldDisplayMode::MAIN;
273 } else if (!xmlStrcmp(displayMode, reinterpret_cast<const xmlChar*>("FOLD_DISPLAY_MODE_SUB"))) {
274 physicalSize.foldDisplayMode_ = FoldDisplayMode::SUB;
275 } else {
276 physicalSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
277 }
278 if (IsNumber(displaySizeArray[0]) && IsNumber(displaySizeArray[1])) {
279 physicalSize.physicalWidth_ = static_cast<uint32_t>(std::stoi(displaySizeArray[0]));
280 physicalSize.physicalHeight_ = static_cast<uint32_t>(std::stoi(displaySizeArray[1]));
281 }
282 displayPhysicalResolution_.emplace_back(physicalSize);
283 xmlFree(displayModeContext);
284 xmlFree(displayMode);
285 }
286
GetAllDisplayPhysicalConfig()287 std::vector<DisplayPhysicalResolution> ScreenSceneConfig::GetAllDisplayPhysicalConfig()
288 {
289 return displayPhysicalResolution_;
290 }
291
ReadEnableConfigInfo(const xmlNodePtr & currNode)292 void ScreenSceneConfig::ReadEnableConfigInfo(const xmlNodePtr& currNode)
293 {
294 xmlChar* enable = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("enable"));
295 if (enable == nullptr) {
296 TLOGE(WmsLogTag::DMS, "[SsConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
297 return;
298 }
299
300 std::string nodeName = reinterpret_cast<const char *>(currNode->name);
301 if (!xmlStrcmp(enable, reinterpret_cast<const xmlChar*>("true"))) {
302 enableConfig_[nodeName] = true;
303 if (xmlNodeMap_[IS_WATERFALL_DISPLAY] == nodeName) {
304 isWaterfallDisplay_ = true;
305 } else if (xmlNodeMap_[IS_CURVED_COMPRESS_ENABLED] == nodeName) {
306 isScreenCompressionEnableInLandscape_ = true;
307 }
308 } else {
309 enableConfig_[nodeName] = false;
310 }
311 xmlFree(enable);
312 }
313
ReadStringConfigInfo(const xmlNodePtr & currNode)314 void ScreenSceneConfig::ReadStringConfigInfo(const xmlNodePtr& currNode)
315 {
316 xmlChar* context = xmlNodeGetContent(currNode);
317 if (context == nullptr) {
318 TLOGE(WmsLogTag::DMS, "[SsConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
319 return;
320 }
321
322 std::string inputString = reinterpret_cast<const char*>(context);
323 std::string nodeName = reinterpret_cast<const char*>(currNode->name);
324 stringConfig_[nodeName] = inputString;
325 xmlFree(context);
326 }
327
ReadStringListConfigInfo(const xmlNodePtr & rootNode,std::string name)328 void ScreenSceneConfig::ReadStringListConfigInfo(const xmlNodePtr& rootNode, std::string name)
329 {
330 if (rootNode == nullptr || rootNode->name == nullptr) {
331 TLOGE(WmsLogTag::DMS, "[SsConfig] get root element failed!");
332 return;
333 }
334 xmlChar* rootContext = xmlNodeGetContent(rootNode);
335 if (rootContext == nullptr) {
336 TLOGE(WmsLogTag::DMS, "rootContext is null");
337 return;
338 }
339 std::vector<std::string> stringVec;
340 for (xmlNodePtr curNodePtr = rootNode->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
341 if (!IsValidNode(*curNodePtr)) {
342 TLOGE(WmsLogTag::DMS, "SsConfig]: invalid node!");
343 continue;
344 }
345 xmlChar* context = xmlNodeGetContent(curNodePtr);
346 std::string str = reinterpret_cast<const char*>(context);
347 stringVec.emplace_back(str);
348 xmlFree(context);
349 }
350 stringListConfig_[name] = stringVec;
351 xmlFree(rootContext);
352 }
353
GetEnableConfig()354 const std::map<std::string, bool>& ScreenSceneConfig::GetEnableConfig()
355 {
356 return enableConfig_;
357 }
358
GetIntNumbersConfig()359 const std::map<std::string, std::vector<int>>& ScreenSceneConfig::GetIntNumbersConfig()
360 {
361 return intNumbersConfig_;
362 }
363
GetStringConfig()364 const std::map<std::string, std::string>& ScreenSceneConfig::GetStringConfig()
365 {
366 return stringConfig_;
367 }
368
GetStringListConfig()369 const std::map<std::string, std::vector<std::string>>& ScreenSceneConfig::GetStringListConfig()
370 {
371 return stringListConfig_;
372 }
373
DumpConfig()374 void ScreenSceneConfig::DumpConfig()
375 {
376 for (auto& enable : enableConfig_) {
377 TLOGI(WmsLogTag::DMS, "[SsConfig] Enable: %{public}s %{public}u", enable.first.c_str(), enable.second);
378 }
379 for (auto& numbers : intNumbersConfig_) {
380 TLOGI(WmsLogTag::DMS, "[SsConfig] Numbers: %{public}s %{public}zu",
381 numbers.first.c_str(), numbers.second.size());
382 for (auto& num : numbers.second) {
383 TLOGI(WmsLogTag::DMS, "[SsConfig] Num: %{public}d", num);
384 }
385 }
386 for (auto& string : stringConfig_) {
387 TLOGI(WmsLogTag::DMS, "[SsConfig] String: %{public}s", string.first.c_str());
388 }
389 }
390
SetCutoutSvgPath(uint64_t displayId,const std::string & svgPath)391 void ScreenSceneConfig::SetCutoutSvgPath(uint64_t displayId, const std::string& svgPath)
392 {
393 cutoutBoundaryRectMap_.clear();
394 cutoutBoundaryRectMap_[displayId].emplace_back(CalcCutoutBoundaryRect(svgPath));
395 }
396
SetSubCutoutSvgPath(const std::string & svgPath)397 void ScreenSceneConfig::SetSubCutoutSvgPath(const std::string& svgPath)
398 {
399 subCutoutBoundaryRect_.clear();
400 subCutoutBoundaryRect_.emplace_back(CalcCutoutBoundaryRect(svgPath));
401 }
402
CalcCutoutBoundaryRect(std::string svgPath)403 DMRect ScreenSceneConfig::CalcCutoutBoundaryRect(std::string svgPath)
404 {
405 DMRect emptyRect = { 0, 0, 0, 0 };
406 SkPath skCutoutSvgPath;
407 if (!SkParsePath::FromSVGString(svgPath.c_str(), &skCutoutSvgPath)) {
408 TLOGE(WmsLogTag::DMS, "Parse svg string path failed.");
409 return emptyRect;
410 }
411 SkRect skRect = skCutoutSvgPath.computeTightBounds();
412 if (skRect.isEmpty()) {
413 TLOGW(WmsLogTag::DMS, "Get empty skRect");
414 return emptyRect;
415 }
416 SkIRect skiRect = skRect.roundOut();
417 if (skiRect.isEmpty()) {
418 TLOGW(WmsLogTag::DMS, "Get empty skiRect");
419 return emptyRect;
420 }
421 int32_t left = static_cast<int32_t>(skiRect.left());
422 int32_t top = static_cast<int32_t>(skiRect.top());
423 uint32_t width = static_cast<uint32_t>(skiRect.width());
424 uint32_t height = static_cast<uint32_t>(skiRect.height());
425 TLOGI(WmsLogTag::DMS,
426 "calc cutout boundary rect - left: [%{public}d top: %{public}d width: %{public}u height: %{public}u]",
427 left, top, width, height);
428 DMRect cutoutMinOuterRect = {
429 .posX_ = left,
430 .posY_ = top,
431 .width_ = width,
432 .height_ = height
433 };
434 return cutoutMinOuterRect;
435 }
436
GetCutoutBoundaryRect(uint64_t displayId)437 std::vector<DMRect> ScreenSceneConfig::GetCutoutBoundaryRect(uint64_t displayId)
438 {
439 if (cutoutBoundaryRectMap_.count(displayId) == 0) {
440 return {};
441 }
442 return cutoutBoundaryRectMap_[displayId];
443 }
444
GetSubCutoutBoundaryRect()445 std::vector<DMRect> ScreenSceneConfig::GetSubCutoutBoundaryRect()
446 {
447 return subCutoutBoundaryRect_;
448 }
449
IsWaterfallDisplay()450 bool ScreenSceneConfig::IsWaterfallDisplay()
451 {
452 return isWaterfallDisplay_;
453 }
454
SetCurvedCompressionAreaInLandscape()455 void ScreenSceneConfig::SetCurvedCompressionAreaInLandscape()
456 {
457 if (intNumbersConfig_[xmlNodeMap_[CURVED_AREA_IN_LANDSCAPE]].size() > 0) {
458 curvedAreaInLandscape_ = static_cast<uint32_t>(intNumbersConfig_[xmlNodeMap_[CURVED_AREA_IN_LANDSCAPE]][0]);
459 } else {
460 TLOGW(WmsLogTag::DMS, "waterfallAreaCompressionSizeWhenHorzontal value is not exist");
461 }
462 }
463
GetCurvedScreenBoundaryConfig()464 std::vector<int> ScreenSceneConfig::GetCurvedScreenBoundaryConfig()
465 {
466 return intNumbersConfig_[xmlNodeMap_[CURVED_SCREEN_BOUNDARY]];
467 }
468
GetCurvedCompressionAreaInLandscape()469 uint32_t ScreenSceneConfig::GetCurvedCompressionAreaInLandscape()
470 {
471 if (!isWaterfallDisplay_ || !isScreenCompressionEnableInLandscape_) {
472 TLOGW(WmsLogTag::DMS, "not waterfall screen or waterfall compression is not enabled");
473 return NO_WATERFALL_DISPLAY_COMPRESSION_SIZE;
474 }
475 return curvedAreaInLandscape_;
476 }
477
IsSupportRotateWithSensor()478 bool ScreenSceneConfig::IsSupportRotateWithSensor()
479 {
480 if (enableConfig_.count("supportRotateWithSensor") != 0) {
481 return static_cast<bool>(enableConfig_["supportRotateWithSensor"]);
482 }
483 return false;
484 }
GetExternalScreenDefaultMode()485 std::string ScreenSceneConfig::GetExternalScreenDefaultMode()
486 {
487 if (stringConfig_.count("externalScreenDefaultMode") != 0) {
488 return static_cast<std::string>(stringConfig_["externalScreenDefaultMode"]);
489 }
490 return "";
491 }
492
493 } // namespace OHOS::Rosen
494