1 /*
2 * Copyright (c) 2021-2025 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 "core/components/theme/theme_manager_impl.h"
17
18 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
19 #include "core/common/resource/resource_manager.h"
20 #include "core/components/badge/badge_theme.h"
21 #include "core/components/button/button_theme.h"
22 #include "core/components/calendar/calendar_theme.h"
23 #include "core/components/camera/camera_theme.h"
24 #include "core/components/checkable/checkable_theme.h"
25 #include "core/components/clock/clock_theme.h"
26 #include "core/components/close_icon/close_icon_theme.h"
27 #include "core/components/counter/counter_theme.h"
28 #include "core/components/data_panel/data_panel_theme.h"
29 #include "core/components/dialog/dialog_theme.h"
30 #include "core/components/divider/divider_theme.h"
31 #include "core/components/drag_bar/drag_bar_theme.h"
32 #include "core/components/focus_animation/focus_animation_theme.h"
33 #include "core/components/hyperlink/hyperlink_theme.h"
34 #include "core/components/image/image_theme.h"
35 #include "core/components/indexer/indexer_theme.h"
36 #include "core/components/list/list_item_theme.h"
37 #include "core/components/list/list_theme.h"
38 #include "core/components/list/arc_list_item_theme.h"
39 #include "core/components/list/arc_list_theme.h"
40 #include "core/components/marquee/marquee_theme.h"
41 #include "core/components/navigation_bar/navigation_bar_theme.h"
42 #include "core/components/picker/picker_theme.h"
43 #include "core/components/piece/piece_theme.h"
44 #include "core/components/popup/popup_theme.h"
45 #include "core/components/progress/progress_theme.h"
46 #include "core/components/qrcode/qrcode_theme.h"
47 #include "core/components/rating/rating_theme.h"
48 #include "core/components/refresh/refresh_theme.h"
49 #include "core/components/scroll/scroll_bar_theme.h"
50 #include "core/components/search/search_theme.h"
51 #include "core/components/select/select_theme.h"
52 #include "core/components/semi_modal/semi_modal_theme.h"
53 #include "core/components/slider/slider_theme.h"
54 #include "core/components/stepper/stepper_theme.h"
55 #include "core/components/tab_bar/tab_theme.h"
56 #include "core/components/text_field/textfield_theme.h"
57 #include "core/components/text_overlay/text_overlay_theme.h"
58 #include "core/components/theme/advanced_pattern_theme.h"
59 #include "core/components/theme/app_theme.h"
60 #include "core/components/theme/blur_style_theme.h"
61 #include "core/components/theme/card_theme.h"
62 #include "core/components/theme/icon_theme.h"
63 #include "core/components/theme/shadow_theme.h"
64 #include "core/components/toast/toast_theme.h"
65 #include "core/components/toggle/toggle_theme.h"
66 #include "core/components/tool_bar/tool_bar_theme.h"
67 #include "core/components/video/video_theme.h"
68 #include "core/components_ng/pattern/app_bar/app_bar_theme.h"
69 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
70 #include "core/components_ng/pattern/form/form_theme.h"
71 #include "core/components_ng/pattern/gauge/gauge_theme.h"
72 #include "core/components_ng/pattern/security_component/security_component_theme.h"
73 #include "core/components_ng/pattern/side_bar/side_bar_theme.h"
74 #include "core/components_v2/pattern_lock/pattern_lock_theme.h"
75 #include "core/components_ng/pattern/grid/grid_item_theme.h"
76 #include "core/components_ng/pattern/linear_indicator/linear_indicator_theme.h"
77 #include "core/components_ng/pattern/menu/menu_theme.h"
78 #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h"
79 #include "core/components_ng/pattern/scrollable/scrollable_theme.h"
80 #include "core/components_ng/pattern/select/select_theme_wrapper.h"
81 #include "core/components_ng/pattern/swiper/swiper_theme.h"
82 #include "core/components_ng/pattern/toggle/switch_theme_wrapper.h"
83 #include "core/components_ng/pattern/toggle/toggle_theme_wrapper.h"
84 #include "core/components_ng/token_theme/token_theme_storage.h"
85 #include "core/components_ng/pattern/checkbox/checkbox_theme_wrapper.h"
86 #include "core/components_ng/pattern/counter/counter_theme_wrapper.h"
87 #include "frameworks/core/components/text_clock/text_clock_theme.h"
88 #include "core/components_ng/pattern/text_clock/text_clock_theme_wrapper.h"
89 #include "core/components_ng/pattern/progress/progress_theme_wrapper.h"
90 #include "core/components_ng/pattern/divider/divider_theme_wrapper.h"
91 #include "core/components_ng/pattern/rich_editor/rich_editor_theme_wrapper.h"
92 #include "core/components_ng/pattern/search/search_theme_wrapper.h"
93 #include "core/components_ng/pattern/text/text_theme_wrapper.h"
94 #include "core/components_ng/pattern/text_field/text_field_theme_wrapper.h"
95 #include "core/components_ng/pattern/picker/picker_theme_wrapper.h"
96 #include "core/components_ng/pattern/navigation/navigation_bar_theme_wrapper.h"
97 #include "core/common/agingadapation/aging_adapation_dialog_theme_wrapper.h"
98 #include "core/components_ng/pattern/side_bar/side_bar_theme_wrapper.h"
99
100 namespace OHOS::Ace {
101 namespace {
102 template<class T>
ThemeBuildFunc(const RefPtr<ThemeConstants> & themeConstants)103 RefPtr<Theme> ThemeBuildFunc(const RefPtr<ThemeConstants>& themeConstants)
104 {
105 return T().Build(themeConstants);
106 }
107
108 const std::unordered_map<ThemeType, RefPtr<Theme>(*)(const RefPtr<ThemeConstants>& themeConstants)> THEME_BUILDERS = {
109 { AppTheme::TypeId(), &ThemeBuildFunc<AppTheme::Builder> },
110 { ButtonTheme::TypeId(), &ThemeBuildFunc<ButtonTheme::Builder> },
111 { PickerTheme::TypeId(), &ThemeBuildFunc<PickerTheme::Builder> },
112 { CheckboxTheme::TypeId(), &ThemeBuildFunc<CheckboxTheme::Builder> },
113 { SwitchTheme::TypeId(), &ThemeBuildFunc<SwitchTheme::Builder> },
114 { RadioTheme::TypeId(), &ThemeBuildFunc<RadioTheme::Builder> },
115 { DialogTheme::TypeId(), &ThemeBuildFunc<DialogTheme::Builder> },
116 { MarqueeTheme::TypeId(), &ThemeBuildFunc<MarqueeTheme::Builder> },
117 { NavigationBarTheme::TypeId(), &ThemeBuildFunc<NavigationBarTheme::Builder> },
118 { SelectTheme::TypeId(), &ThemeBuildFunc<SelectTheme::Builder> },
119 { SliderTheme::TypeId(), &ThemeBuildFunc<SliderTheme::Builder> },
120 { SwiperIndicatorTheme::TypeId(), &ThemeBuildFunc<SwiperIndicatorTheme::Builder> },
121 { PopupTheme::TypeId(), &ThemeBuildFunc<PopupTheme::Builder> },
122 { ProgressTheme::TypeId(), &ThemeBuildFunc<ProgressTheme::Builder> },
123 { VideoTheme::TypeId(), &ThemeBuildFunc<VideoTheme::Builder> },
124 { TabTheme::TypeId(), &ThemeBuildFunc<TabTheme::Builder> },
125 { RefreshTheme::TypeId(), &ThemeBuildFunc<RefreshTheme::Builder> },
126 { ListTheme::TypeId(), &ThemeBuildFunc<ListTheme::Builder> },
127 { ListItemTheme::TypeId(), &ThemeBuildFunc<ListItemTheme::Builder> },
128 { ArcListTheme::TypeId(), &ThemeBuildFunc<ArcListTheme::Builder> },
129 { ArcListItemTheme::TypeId(), &ThemeBuildFunc<ArcListItemTheme::Builder> },
130 { ToastTheme::TypeId(), &ThemeBuildFunc<ToastTheme::Builder> },
131 { TextTheme::TypeId(), &ThemeBuildFunc<TextTheme::Builder> },
132 { TextClockTheme::TypeId(), &ThemeBuildFunc<TextClockTheme::Builder> },
133 { RatingTheme::TypeId(), &ThemeBuildFunc<RatingTheme::Builder> },
134 { TextFieldTheme::TypeId(), &ThemeBuildFunc<TextFieldTheme::Builder> },
135 { FocusAnimationTheme::TypeId(), &ThemeBuildFunc<FocusAnimationTheme::Builder> },
136 { ScrollBarTheme::TypeId(), &ThemeBuildFunc<ScrollBarTheme::Builder> },
137 { CalendarTheme::TypeId(), &ThemeBuildFunc<CalendarTheme::Builder> },
138 { SearchTheme::TypeId(), &ThemeBuildFunc<SearchTheme::Builder> },
139 { TextOverlayTheme::TypeId(), &ThemeBuildFunc<TextOverlayTheme::Builder> },
140 { DividerTheme::TypeId(), &ThemeBuildFunc<DividerTheme::Builder> },
141 { ToggleTheme::TypeId(), &ThemeBuildFunc<ToggleTheme::Builder> },
142 { ClockTheme::TypeId(), &ThemeBuildFunc<ClockTheme::Builder> },
143 { DataPanelTheme::TypeId(), &ThemeBuildFunc<DataPanelTheme::Builder> },
144 { BadgeTheme::TypeId(), &ThemeBuildFunc<BadgeTheme::Builder> },
145 { PieceTheme::TypeId(), &ThemeBuildFunc<PieceTheme::Builder> },
146 { StepperTheme::TypeId(), &ThemeBuildFunc<StepperTheme::Builder> },
147 { ToolBarTheme::TypeId(), &ThemeBuildFunc<ToolBarTheme::Builder> },
148 { CardTheme::TypeId(), &ThemeBuildFunc<CardTheme::Builder> },
149 { QrcodeTheme::TypeId(), &ThemeBuildFunc<QrcodeTheme::Builder> },
150 { CameraTheme::TypeId(), &ThemeBuildFunc<CameraTheme::Builder> },
151 { HyperlinkTheme::TypeId(), &ThemeBuildFunc<HyperlinkTheme::Builder> },
152 { ImageTheme::TypeId(), &ThemeBuildFunc<ImageTheme::Builder> },
153 { CounterTheme::TypeId(), &ThemeBuildFunc<CounterTheme::Builder> },
154 { DragBarTheme::TypeId(), &ThemeBuildFunc<DragBarTheme::Builder> },
155 { SemiModalTheme::TypeId(), &ThemeBuildFunc<SemiModalTheme::Builder> },
156 { IconTheme::TypeId(), &ThemeBuildFunc<IconTheme::Builder> },
157 { V2::PatternLockTheme::TypeId(), &ThemeBuildFunc<V2::PatternLockTheme::Builder> },
158 { IndexerTheme::TypeId(), &ThemeBuildFunc<IndexerTheme::Builder> },
159 { NG::AppBarTheme::TypeId(), &ThemeBuildFunc<NG::AppBarTheme::Builder> },
160 { AdvancedPatternTheme::TypeId(), &ThemeBuildFunc<AdvancedPatternTheme::Builder> },
161 { NG::SecurityComponentTheme::TypeId(), &ThemeBuildFunc<NG::SecurityComponentTheme::Builder> },
162 { NG::FormTheme::TypeId(), &ThemeBuildFunc<NG::FormTheme::Builder> },
163 { CloseIconTheme::TypeId(), &ThemeBuildFunc<CloseIconTheme::Builder> },
164 { NG::SideBarTheme::TypeId(), &ThemeBuildFunc<NG::SideBarTheme::Builder> },
165 { NG::RichEditorTheme::TypeId(), &ThemeBuildFunc<NG::RichEditorTheme::Builder> },
166 { NG::GridItemTheme::TypeId(), &ThemeBuildFunc<NG::GridItemTheme::Builder> },
167 { NG::MenuTheme::TypeId(), &ThemeBuildFunc<NG::MenuTheme::Builder> },
168 { NG::GaugeTheme::TypeId(), &ThemeBuildFunc<NG::GaugeTheme::Builder> },
169 { NG::SheetTheme::TypeId(), &ThemeBuildFunc<NG::SheetTheme::Builder> },
170 { BlurStyleTheme::TypeId(), &ThemeBuildFunc<BlurStyleTheme::Builder> },
171 { ShadowTheme::TypeId(), &ThemeBuildFunc<ShadowTheme::Builder> },
172 { NG::ContainerModalTheme::TypeId(), &ThemeBuildFunc<NG::ContainerModalTheme::Builder> },
173 { AgingAdapationDialogTheme::TypeId(), &ThemeBuildFunc<AgingAdapationDialogTheme::Builder> },
174 { NG::ScrollableTheme::TypeId(), &ThemeBuildFunc<NG::ScrollableTheme::Builder> },
175 { NG::SwiperTheme::TypeId(), &ThemeBuildFunc<NG::SwiperTheme::Builder> },
176 { NG::LinearIndicatorTheme::TypeId(), &ThemeBuildFunc<NG::LinearIndicatorTheme::Builder> },
177 };
178
179 template<class T>
ThemeWrapperBuildFunc(const RefPtr<ThemeConstants> & themeConstants)180 RefPtr<NG::TokenThemeWrapper> ThemeWrapperBuildFunc(const RefPtr<ThemeConstants>& themeConstants)
181 {
182 return T().BuildWrapper(themeConstants);
183 }
184
185 const std::unordered_map<ThemeType, RefPtr<NG::TokenThemeWrapper>(*)(const RefPtr<ThemeConstants>&)>
186 TOKEN_THEME_WRAPPER_BUILDERS = {
187 { CheckboxTheme::TypeId(), &ThemeWrapperBuildFunc<NG::CheckboxThemeWrapper::WrapperBuilder> },
188 { SwitchTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SwitchThemeWrapper::WrapperBuilder> },
189 { ToggleTheme::TypeId(), &ThemeWrapperBuildFunc<NG::ToggleThemeWrapper::WrapperBuilder> },
190 { CounterTheme::TypeId(), &ThemeWrapperBuildFunc<NG::CounterThemeWrapper::WrapperBuilder> },
191 { TextClockTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextClockThemeWrapper::WrapperBuilder> },
192 { DividerTheme::TypeId(), &ThemeWrapperBuildFunc<NG::DividerThemeWrapper::WrapperBuilder> },
193 { NG::RichEditorTheme::TypeId(), &ThemeWrapperBuildFunc<NG::RichEditorThemeWrapper::WrapperBuilder> },
194 { SearchTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SearchThemeWrapper::WrapperBuilder> },
195 { TextTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextThemeWrapper::WrapperBuilder> },
196 { TextFieldTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextFieldThemeWrapper::WrapperBuilder> },
197 { PickerTheme::TypeId(), &ThemeWrapperBuildFunc<NG::PickerThemeWrapper::WrapperBuilder> },
198 { ProgressTheme::TypeId(), &ThemeWrapperBuildFunc<NG::ProgressThemeWrapper::WrapperBuilder> },
199 { SelectTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SelectThemeWrapper::WrapperBuilder> },
200 { NavigationBarTheme::TypeId(), &ThemeWrapperBuildFunc<NG::NavigationBarThemeWrapper::WrapperBuilder> },
201 { AgingAdapationDialogTheme::TypeId(),
202 &ThemeWrapperBuildFunc<NG::AgingAdapationDialogThemeWrapper::WrapperBuilder> },
203 { NG::SideBarTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SideBarThemeWrapper::WrapperBuilder> }
204 };
205
206 std::unordered_map<ThemeType, Ace::Kit::BuildFunc> THEME_BUILDERS_KIT;
207 } // namespace
208
ThemeManagerImpl()209 ThemeManagerImpl::ThemeManagerImpl()
210 {
211 auto resAdapter = ResourceAdapter::Create();
212 themeConstants_ = AceType::MakeRefPtr<ThemeConstants>(resAdapter);
213 }
214
ThemeManagerImpl(RefPtr<ResourceAdapter> & resourceAdapter)215 ThemeManagerImpl::ThemeManagerImpl(RefPtr<ResourceAdapter>& resourceAdapter)
216 {
217 themeConstants_ = AceType::MakeRefPtr<ThemeConstants>(resourceAdapter);
218 }
219
RegisterThemeKit(ThemeType type,Ace::Kit::BuildFunc func)220 void ThemeManagerImpl::RegisterThemeKit(ThemeType type, Ace::Kit::BuildFunc func)
221 {
222 auto findIter = themes_.find(type);
223 if (findIter != themes_.end()) {
224 return;
225 }
226 THEME_BUILDERS_KIT.insert({ type, func });
227 }
228
GetTheme(ThemeType type)229 RefPtr<Theme> ThemeManagerImpl::GetTheme(ThemeType type)
230 {
231 auto findIter = themes_.find(type);
232 if (findIter != themes_.end()) {
233 return findIter->second;
234 }
235
236 auto theme = GetThemeKit(type);
237 CHECK_NULL_RETURN(theme, GetThemeOrigin(type));
238 return theme;
239 }
240
GetThemeOrigin(ThemeType type)241 RefPtr<Theme> ThemeManagerImpl::GetThemeOrigin(ThemeType type)
242 {
243 auto builderIter = THEME_BUILDERS.find(type);
244 if (builderIter == THEME_BUILDERS.end()) {
245 return nullptr;
246 }
247
248 if (auto pipelineContext = NG::PipelineContext::GetCurrentContext(); pipelineContext) {
249 ColorMode localMode = pipelineContext->GetLocalColorMode();
250 ColorMode systemMode = pipelineContext->GetColorMode();
251 bool needRestore = false;
252 if (localMode != ColorMode::COLOR_MODE_UNDEFINED && localMode != systemMode) {
253 // Ordinary themes should work in system color mode. Only theme wrappers support local color mode.
254 ResourceManager::GetInstance().UpdateColorMode(systemMode);
255 pipelineContext->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
256 needRestore = true;
257 }
258 auto theme = builderIter->second(themeConstants_);
259 if (needRestore) {
260 pipelineContext->SetLocalColorMode(localMode);
261 ResourceManager::GetInstance().UpdateColorMode(localMode);
262 }
263 themes_.emplace(type, theme);
264 return theme;
265 }
266
267 auto theme = builderIter->second(themeConstants_);
268 themes_.emplace(type, theme);
269 return theme;
270 }
271
GetThemeKit(ThemeType type)272 RefPtr<Theme> ThemeManagerImpl::GetThemeKit(ThemeType type)
273 {
274 auto builderIterKit = THEME_BUILDERS_KIT.find(type);
275 if (builderIterKit == THEME_BUILDERS_KIT.end()) {
276 return nullptr;
277 }
278
279 if (auto pipelineContext = NG::PipelineContext::GetCurrentContext(); pipelineContext) {
280 ColorMode localMode = pipelineContext->GetLocalColorMode();
281 ColorMode systemMode = pipelineContext->GetColorMode();
282 bool needRestore = false;
283 if (localMode != ColorMode::COLOR_MODE_UNDEFINED && localMode != systemMode) {
284 // Ordinary themes should work in system color mode. Only theme wrappers support local color mode.
285 ResourceManager::GetInstance().UpdateColorMode(systemMode);
286 pipelineContext->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
287 needRestore = true;
288 }
289 auto theme = builderIterKit->second();
290 if (needRestore) {
291 pipelineContext->SetLocalColorMode(localMode);
292 ResourceManager::GetInstance().UpdateColorMode(localMode);
293 }
294 themes_.emplace(type, theme);
295 return theme;
296 }
297
298 auto theme = builderIterKit->second();
299 themes_.emplace(type, theme);
300 return theme;
301 }
302
GetTheme(ThemeType type,NG::TokenThemeScopeId themeScopeId)303 RefPtr<Theme> ThemeManagerImpl::GetTheme(ThemeType type, NG::TokenThemeScopeId themeScopeId)
304 {
305 auto tokenTheme = NG::TokenThemeStorage::GetInstance()->GetTheme(themeScopeId);
306 if (!tokenTheme) {
307 return GetTheme(type);
308 }
309
310 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
311 CHECK_NULL_RETURN(pipelineContext, GetTheme(type));
312 ColorMode currentMode = GetCurrentColorMode();
313 ColorMode themeMode = tokenTheme->GetColorMode();
314 auto& themeWrappers = GetThemeWrappers(themeMode == ColorMode::COLOR_MODE_UNDEFINED ? currentMode : themeMode);
315 auto findIter = themeWrappers.find(type);
316 if (findIter != themeWrappers.end()) {
317 auto wrapper = findIter->second;
318 wrapper->ApplyTokenTheme(*tokenTheme);
319 return AceType::DynamicCast<Theme>(wrapper);
320 }
321
322 auto builderIter = TOKEN_THEME_WRAPPER_BUILDERS.find(type);
323 if (builderIter == TOKEN_THEME_WRAPPER_BUILDERS.end()) {
324 return GetTheme(type);
325 }
326
327 bool needRestore = false;
328 if (themeMode != ColorMode::COLOR_MODE_UNDEFINED && themeMode != currentMode) {
329 // Local color mode of the current theme does not match actual color scheme.
330 // Current color mode is system. Need to switch to local color mode temporarily.
331 ResourceManager::GetInstance().UpdateColorMode(themeMode);
332 pipelineContext->SetLocalColorMode(themeMode);
333 needRestore = true;
334 }
335 auto wrapper = builderIter->second(themeConstants_);
336 if (needRestore) {
337 // Switching resource manager back into system color mode
338 pipelineContext->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
339 ResourceManager::GetInstance().UpdateColorMode(currentMode);
340 }
341 wrapper->ApplyTokenTheme(*tokenTheme);
342 themeWrappers.emplace(type, wrapper);
343 return AceType::DynamicCast<Theme>(wrapper);
344 }
345
GetBackgroundColor() const346 Color ThemeManagerImpl::GetBackgroundColor() const
347 {
348 auto findIter = themes_.find(AppTheme::TypeId());
349 if (findIter != themes_.end()) {
350 auto appTheme = AceType::DynamicCast<AppTheme>(findIter->second);
351 if (appTheme) {
352 return appTheme->GetBackgroundColor();
353 }
354 }
355 // Parse attr from system theme style.
356 auto themeStyle = themeConstants_->GetThemeStyle();
357 auto prebuildColor = themeConstants_->GetColor(THEME_APP_BACKGROUND);
358 if (!themeStyle) {
359 return prebuildColor;
360 }
361 if (themeStyle->HasAttr(THEME_ATTR_BG_COLOR) && !themeConstants_->HasCustomStyle(THEME_APP_BACKGROUND)) {
362 // Get from resource.
363 return themeStyle->GetAttr<Color>(THEME_ATTR_BG_COLOR, Color::BLACK);
364 } else {
365 // Get from prebuild or custom color.
366 return prebuildColor;
367 }
368 }
369
LoadResourceThemes()370 void ThemeManagerImpl::LoadResourceThemes()
371 {
372 themes_.clear();
373 themeWrappersLight_.clear();
374 themeWrappersDark_.clear();
375 themeConstants_->LoadTheme(currentThemeId_);
376 }
377
GetThemeWrappers(ColorMode mode)378 ThemeManagerImpl::ThemeWrappers& ThemeManagerImpl::GetThemeWrappers(ColorMode mode)
379 {
380 return mode == ColorMode::DARK ? themeWrappersDark_ : themeWrappersLight_;
381 }
382
GetCurrentColorMode() const383 ColorMode ThemeManagerImpl::GetCurrentColorMode() const
384 {
385 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
386 ColorMode systemMode = Container::CurrentColorMode();
387 CHECK_NULL_RETURN(pipelineContext, systemMode);
388 ColorMode localMode = pipelineContext->GetLocalColorMode();
389 return localMode == ColorMode::COLOR_MODE_UNDEFINED ? systemMode : localMode;
390 }
391 } // namespace OHOS::Ace
392