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/text_overlay/text_overlay_theme_wrapper.h"
59 #include "core/components/theme/advanced_pattern_theme.h"
60 #include "core/components/theme/app_theme.h"
61 #include "core/components/theme/blur_style_theme.h"
62 #include "core/components/theme/card_theme.h"
63 #include "core/components/theme/icon_theme.h"
64 #include "core/components/theme/shadow_theme.h"
65 #include "core/components/toast/toast_theme.h"
66 #include "core/components/toggle/toggle_theme.h"
67 #include "core/components/tool_bar/tool_bar_theme.h"
68 #include "core/components/video/video_theme.h"
69 #include "core/components_ng/pattern/app_bar/app_bar_theme.h"
70 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
71 #include "core/components_ng/pattern/form/form_theme.h"
72 #include "core/components_ng/pattern/gauge/gauge_theme.h"
73 #include "core/components_ng/pattern/refresh/refresh_theme_ng.h"
74 #include "core/components_ng/pattern/security_component/security_component_theme.h"
75 #include "core/components_ng/pattern/side_bar/side_bar_theme.h"
76 #include "core/components_v2/pattern_lock/pattern_lock_theme.h"
77 #include "core/components_ng/pattern/grid/grid_item_theme.h"
78 #include "core/components_ng/pattern/linear_indicator/linear_indicator_theme.h"
79 #include "core/components_ng/pattern/menu/menu_theme.h"
80 #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h"
81 #include "core/components_ng/pattern/scrollable/scrollable_theme.h"
82 #include "core/components_ng/pattern/select/select_theme_wrapper.h"
83 #include "core/components_ng/pattern/swiper/swiper_theme.h"
84 #include "core/components_ng/pattern/toggle/switch_theme_wrapper.h"
85 #include "core/components_ng/pattern/toggle/toggle_theme_wrapper.h"
86 #include "core/components_ng/token_theme/token_theme_storage.h"
87 #include "core/components_ng/pattern/checkbox/checkbox_theme_wrapper.h"
88 #include "core/components_ng/pattern/counter/counter_theme_wrapper.h"
89 #include "frameworks/core/components/text_clock/text_clock_theme.h"
90 #include "core/components_ng/pattern/text_clock/text_clock_theme_wrapper.h"
91 #include "core/components_ng/pattern/progress/progress_theme_wrapper.h"
92 #include "core/components_ng/pattern/divider/divider_theme_wrapper.h"
93 #include "core/components_ng/pattern/rich_editor/rich_editor_theme_wrapper.h"
94 #include "core/components_ng/pattern/search/search_theme_wrapper.h"
95 #include "core/components_ng/pattern/slider/slider_theme_wrapper.h"
96 #include "core/components_ng/pattern/text/text_theme_wrapper.h"
97 #include "core/components_ng/pattern/text_field/text_field_theme_wrapper.h"
98 #include "core/components_ng/pattern/picker/picker_theme_wrapper.h"
99 #include "core/components_ng/pattern/navigation/navigation_bar_theme_wrapper.h"
100 #include "core/common/agingadapation/aging_adapation_dialog_theme_wrapper.h"
101 #include "core/components_ng/pattern/side_bar/side_bar_theme_wrapper.h"
102
103 namespace OHOS::Ace {
104 namespace {
105 template<class T>
ThemeBuildFunc(const RefPtr<ThemeConstants> & themeConstants)106 RefPtr<Theme> ThemeBuildFunc(const RefPtr<ThemeConstants>& themeConstants)
107 {
108 return T().Build(themeConstants);
109 }
110
111 const std::unordered_map<ThemeType, RefPtr<Theme>(*)(const RefPtr<ThemeConstants>& themeConstants)> THEME_BUILDERS = {
112 { AppTheme::TypeId(), &ThemeBuildFunc<AppTheme::Builder> },
113 { ButtonTheme::TypeId(), &ThemeBuildFunc<ButtonTheme::Builder> },
114 { PickerTheme::TypeId(), &ThemeBuildFunc<PickerTheme::Builder> },
115 { CheckboxTheme::TypeId(), &ThemeBuildFunc<CheckboxTheme::Builder> },
116 { SwitchTheme::TypeId(), &ThemeBuildFunc<SwitchTheme::Builder> },
117 { RadioTheme::TypeId(), &ThemeBuildFunc<RadioTheme::Builder> },
118 { DialogTheme::TypeId(), &ThemeBuildFunc<DialogTheme::Builder> },
119 { MarqueeTheme::TypeId(), &ThemeBuildFunc<MarqueeTheme::Builder> },
120 { NavigationBarTheme::TypeId(), &ThemeBuildFunc<NavigationBarTheme::Builder> },
121 { SelectTheme::TypeId(), &ThemeBuildFunc<SelectTheme::Builder> },
122 { SliderTheme::TypeId(), &ThemeBuildFunc<SliderTheme::Builder> },
123 { SwiperIndicatorTheme::TypeId(), &ThemeBuildFunc<SwiperIndicatorTheme::Builder> },
124 { PopupTheme::TypeId(), &ThemeBuildFunc<PopupTheme::Builder> },
125 { ProgressTheme::TypeId(), &ThemeBuildFunc<ProgressTheme::Builder> },
126 { VideoTheme::TypeId(), &ThemeBuildFunc<VideoTheme::Builder> },
127 { TabTheme::TypeId(), &ThemeBuildFunc<TabTheme::Builder> },
128 { RefreshTheme::TypeId(), &ThemeBuildFunc<RefreshTheme::Builder> },
129 { ListTheme::TypeId(), &ThemeBuildFunc<ListTheme::Builder> },
130 { ListItemTheme::TypeId(), &ThemeBuildFunc<ListItemTheme::Builder> },
131 { ArcListTheme::TypeId(), &ThemeBuildFunc<ArcListTheme::Builder> },
132 { ArcListItemTheme::TypeId(), &ThemeBuildFunc<ArcListItemTheme::Builder> },
133 { ToastTheme::TypeId(), &ThemeBuildFunc<ToastTheme::Builder> },
134 { TextTheme::TypeId(), &ThemeBuildFunc<TextTheme::Builder> },
135 { TextClockTheme::TypeId(), &ThemeBuildFunc<TextClockTheme::Builder> },
136 { RatingTheme::TypeId(), &ThemeBuildFunc<RatingTheme::Builder> },
137 { TextFieldTheme::TypeId(), &ThemeBuildFunc<TextFieldTheme::Builder> },
138 { FocusAnimationTheme::TypeId(), &ThemeBuildFunc<FocusAnimationTheme::Builder> },
139 { ScrollBarTheme::TypeId(), &ThemeBuildFunc<ScrollBarTheme::Builder> },
140 { CalendarTheme::TypeId(), &ThemeBuildFunc<CalendarTheme::Builder> },
141 { SearchTheme::TypeId(), &ThemeBuildFunc<SearchTheme::Builder> },
142 { TextOverlayTheme::TypeId(), &ThemeBuildFunc<TextOverlayTheme::Builder> },
143 { DividerTheme::TypeId(), &ThemeBuildFunc<DividerTheme::Builder> },
144 { ToggleTheme::TypeId(), &ThemeBuildFunc<ToggleTheme::Builder> },
145 { ClockTheme::TypeId(), &ThemeBuildFunc<ClockTheme::Builder> },
146 { DataPanelTheme::TypeId(), &ThemeBuildFunc<DataPanelTheme::Builder> },
147 { BadgeTheme::TypeId(), &ThemeBuildFunc<BadgeTheme::Builder> },
148 { PieceTheme::TypeId(), &ThemeBuildFunc<PieceTheme::Builder> },
149 { StepperTheme::TypeId(), &ThemeBuildFunc<StepperTheme::Builder> },
150 { ToolBarTheme::TypeId(), &ThemeBuildFunc<ToolBarTheme::Builder> },
151 { CardTheme::TypeId(), &ThemeBuildFunc<CardTheme::Builder> },
152 { QrcodeTheme::TypeId(), &ThemeBuildFunc<QrcodeTheme::Builder> },
153 { CameraTheme::TypeId(), &ThemeBuildFunc<CameraTheme::Builder> },
154 { HyperlinkTheme::TypeId(), &ThemeBuildFunc<HyperlinkTheme::Builder> },
155 { ImageTheme::TypeId(), &ThemeBuildFunc<ImageTheme::Builder> },
156 { CounterTheme::TypeId(), &ThemeBuildFunc<CounterTheme::Builder> },
157 { DragBarTheme::TypeId(), &ThemeBuildFunc<DragBarTheme::Builder> },
158 { SemiModalTheme::TypeId(), &ThemeBuildFunc<SemiModalTheme::Builder> },
159 { IconTheme::TypeId(), &ThemeBuildFunc<IconTheme::Builder> },
160 { V2::PatternLockTheme::TypeId(), &ThemeBuildFunc<V2::PatternLockTheme::Builder> },
161 { IndexerTheme::TypeId(), &ThemeBuildFunc<IndexerTheme::Builder> },
162 { NG::AppBarTheme::TypeId(), &ThemeBuildFunc<NG::AppBarTheme::Builder> },
163 { AdvancedPatternTheme::TypeId(), &ThemeBuildFunc<AdvancedPatternTheme::Builder> },
164 { NG::SecurityComponentTheme::TypeId(), &ThemeBuildFunc<NG::SecurityComponentTheme::Builder> },
165 { NG::FormTheme::TypeId(), &ThemeBuildFunc<NG::FormTheme::Builder> },
166 { CloseIconTheme::TypeId(), &ThemeBuildFunc<CloseIconTheme::Builder> },
167 { NG::SideBarTheme::TypeId(), &ThemeBuildFunc<NG::SideBarTheme::Builder> },
168 { NG::RichEditorTheme::TypeId(), &ThemeBuildFunc<NG::RichEditorTheme::Builder> },
169 { NG::GridItemTheme::TypeId(), &ThemeBuildFunc<NG::GridItemTheme::Builder> },
170 { NG::MenuTheme::TypeId(), &ThemeBuildFunc<NG::MenuTheme::Builder> },
171 { NG::GaugeTheme::TypeId(), &ThemeBuildFunc<NG::GaugeTheme::Builder> },
172 { NG::SheetTheme::TypeId(), &ThemeBuildFunc<NG::SheetTheme::Builder> },
173 { BlurStyleTheme::TypeId(), &ThemeBuildFunc<BlurStyleTheme::Builder> },
174 { ShadowTheme::TypeId(), &ThemeBuildFunc<ShadowTheme::Builder> },
175 { NG::ContainerModalTheme::TypeId(), &ThemeBuildFunc<NG::ContainerModalTheme::Builder> },
176 { AgingAdapationDialogTheme::TypeId(), &ThemeBuildFunc<AgingAdapationDialogTheme::Builder> },
177 { NG::ScrollableTheme::TypeId(), &ThemeBuildFunc<NG::ScrollableTheme::Builder> },
178 { NG::SwiperTheme::TypeId(), &ThemeBuildFunc<NG::SwiperTheme::Builder> },
179 { NG::LinearIndicatorTheme::TypeId(), &ThemeBuildFunc<NG::LinearIndicatorTheme::Builder> },
180 { NG::RefreshThemeNG::TypeId(), &ThemeBuildFunc<NG::RefreshThemeNG::Builder> },
181 };
182
183 template<class T>
ThemeWrapperBuildFunc(const RefPtr<ThemeConstants> & themeConstants)184 RefPtr<TokenThemeWrapper> ThemeWrapperBuildFunc(const RefPtr<ThemeConstants>& themeConstants)
185 {
186 return T().BuildWrapper(themeConstants);
187 }
188
189 const std::unordered_map<ThemeType, RefPtr<TokenThemeWrapper>(*)(const RefPtr<ThemeConstants>&)>
190 TOKEN_THEME_WRAPPER_BUILDERS = {
191 { CheckboxTheme::TypeId(), &ThemeWrapperBuildFunc<NG::CheckboxThemeWrapper::WrapperBuilder> },
192 { SwitchTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SwitchThemeWrapper::WrapperBuilder> },
193 { ToggleTheme::TypeId(), &ThemeWrapperBuildFunc<NG::ToggleThemeWrapper::WrapperBuilder> },
194 { CounterTheme::TypeId(), &ThemeWrapperBuildFunc<NG::CounterThemeWrapper::WrapperBuilder> },
195 { TextClockTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextClockThemeWrapper::WrapperBuilder> },
196 { DividerTheme::TypeId(), &ThemeWrapperBuildFunc<NG::DividerThemeWrapper::WrapperBuilder> },
197 { NG::RichEditorTheme::TypeId(), &ThemeWrapperBuildFunc<NG::RichEditorThemeWrapper::WrapperBuilder> },
198 { SearchTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SearchThemeWrapper::WrapperBuilder> },
199 { SliderTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SliderThemeWrapper::WrapperBuilder> },
200 { TextTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextThemeWrapper::WrapperBuilder> },
201 { TextFieldTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextFieldThemeWrapper::WrapperBuilder> },
202 { PickerTheme::TypeId(), &ThemeWrapperBuildFunc<NG::PickerThemeWrapper::WrapperBuilder> },
203 { ProgressTheme::TypeId(), &ThemeWrapperBuildFunc<NG::ProgressThemeWrapper::WrapperBuilder> },
204 { SelectTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SelectThemeWrapper::WrapperBuilder> },
205 { NavigationBarTheme::TypeId(), &ThemeWrapperBuildFunc<NG::NavigationBarThemeWrapper::WrapperBuilder> },
206 { AgingAdapationDialogTheme::TypeId(),
207 &ThemeWrapperBuildFunc<NG::AgingAdapationDialogThemeWrapper::WrapperBuilder> },
208 { NG::SideBarTheme::TypeId(), &ThemeWrapperBuildFunc<NG::SideBarThemeWrapper::WrapperBuilder> },
209 { TextOverlayTheme::TypeId(), &ThemeWrapperBuildFunc<NG::TextOverlayThemeWrapper::WrapperBuilder> }
210 };
211
212 std::unordered_map<ThemeType, Ace::Kit::BuildFunc> THEME_BUILDERS_KIT;
213 std::unordered_map<ThemeType, Ace::Kit::BuildThemeWrapperFunc> TOKEN_THEME_WRAPPER_BUILDERS_KIT;
214 } // namespace
215
ThemeManagerImpl()216 ThemeManagerImpl::ThemeManagerImpl()
217 {
218 auto resAdapter = ResourceAdapter::Create();
219 themeConstants_ = AceType::MakeRefPtr<ThemeConstants>(resAdapter);
220 }
221
ThemeManagerImpl(RefPtr<ResourceAdapter> & resourceAdapter)222 ThemeManagerImpl::ThemeManagerImpl(RefPtr<ResourceAdapter>& resourceAdapter)
223 {
224 themeConstants_ = AceType::MakeRefPtr<ThemeConstants>(resourceAdapter);
225 }
226
RegisterThemeKit(ThemeType type,Ace::Kit::BuildFunc func)227 void ThemeManagerImpl::RegisterThemeKit(ThemeType type, Ace::Kit::BuildFunc func)
228 {
229 auto findIter = themes_.find(type);
230 if (findIter != themes_.end()) {
231 return;
232 }
233 THEME_BUILDERS_KIT.insert({ type, func });
234 }
235
GetTheme(ThemeType type)236 RefPtr<Theme> ThemeManagerImpl::GetTheme(ThemeType type)
237 {
238 auto findIter = themes_.find(type);
239 if (findIter != themes_.end()) {
240 return findIter->second;
241 }
242
243 auto theme = GetThemeKit(type);
244 CHECK_NULL_RETURN(theme, GetThemeOrigin(type));
245 return theme;
246 }
247
GetThemeOrigin(ThemeType type)248 RefPtr<Theme> ThemeManagerImpl::GetThemeOrigin(ThemeType type)
249 {
250 auto builderIter = THEME_BUILDERS.find(type);
251 if (builderIter == THEME_BUILDERS.end()) {
252 return nullptr;
253 }
254
255 auto theme = builderIter->second(themeConstants_);
256 themes_.emplace(type, theme);
257 return theme;
258 }
259
GetThemeKit(ThemeType type)260 RefPtr<Theme> ThemeManagerImpl::GetThemeKit(ThemeType type)
261 {
262 auto builderIterKit = THEME_BUILDERS_KIT.find(type);
263 if (builderIterKit == THEME_BUILDERS_KIT.end()) {
264 return nullptr;
265 }
266
267 if (auto pipeline = NG::PipelineContext::GetCurrentContext(); pipeline) {
268 ColorMode localMode = pipeline->GetLocalColorMode();
269 ColorMode systemMode = pipeline->GetColorMode();
270 bool needRestore = false;
271 if (localMode != ColorMode::COLOR_MODE_UNDEFINED && localMode != systemMode) {
272 // Ordinary themes should work in system color mode. Only theme wrappers support local color mode.
273 ResourceManager::GetInstance().UpdateColorMode(
274 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), systemMode);
275 pipeline->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
276 needRestore = true;
277 }
278 auto theme = builderIterKit->second();
279 if (needRestore) {
280 pipeline->SetLocalColorMode(localMode);
281 ResourceManager::GetInstance().UpdateColorMode(
282 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), localMode);
283 }
284 themes_.emplace(type, theme);
285 return theme;
286 }
287
288 auto theme = builderIterKit->second();
289 themes_.emplace(type, theme);
290 return theme;
291 }
292
293
RegisterCustomThemeKit(ThemeType type,Ace::Kit::BuildThemeWrapperFunc func)294 void ThemeManagerImpl::RegisterCustomThemeKit(ThemeType type, Ace::Kit::BuildThemeWrapperFunc func)
295 {
296 auto findIter = TOKEN_THEME_WRAPPER_BUILDERS_KIT.find(type);
297 if (findIter != TOKEN_THEME_WRAPPER_BUILDERS_KIT.end()) {
298 return;
299 }
300 TOKEN_THEME_WRAPPER_BUILDERS_KIT.insert({ type, func });
301 }
302
GetTheme(ThemeType type,TokenThemeScopeId themeScopeId)303 RefPtr<Theme> ThemeManagerImpl::GetTheme(ThemeType type, TokenThemeScopeId themeScopeId)
304 {
305 auto theme = GetThemeKit(type, themeScopeId);
306 CHECK_NULL_RETURN(theme, GetThemeOrigin(type, themeScopeId));
307 return theme;
308 }
309
GetThemeOrigin(ThemeType type,int32_t themeScopeId)310 RefPtr<Theme> ThemeManagerImpl::GetThemeOrigin(ThemeType type, int32_t themeScopeId)
311 {
312 auto tokenTheme = NG::TokenThemeStorage::GetInstance()->GetTheme(themeScopeId);
313 if (!tokenTheme) {
314 return GetTheme(type);
315 }
316
317 auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
318 CHECK_NULL_RETURN(pipeline, GetTheme(type));
319 ColorMode currentMode = GetCurrentColorMode();
320 ColorMode themeMode = tokenTheme->GetColorMode();
321 auto& themeWrappers = GetThemeWrappers(themeMode == ColorMode::COLOR_MODE_UNDEFINED ? currentMode : themeMode);
322 auto findIter = themeWrappers.find(type);
323 if (findIter != themeWrappers.end()) {
324 auto wrapper = findIter->second;
325 wrapper->ApplyTokenTheme(*tokenTheme);
326 return AceType::DynamicCast<Theme>(wrapper);
327 }
328
329 auto builderIter = TOKEN_THEME_WRAPPER_BUILDERS.find(type);
330 if (builderIter == TOKEN_THEME_WRAPPER_BUILDERS.end()) {
331 return GetTheme(type);
332 }
333
334 bool needRestore = false;
335 if (themeMode != ColorMode::COLOR_MODE_UNDEFINED && themeMode != currentMode) {
336 // Local color mode of the current theme does not match actual color scheme.
337 // Current color mode is system. Need to switch to local color mode temporarily.
338 ResourceManager::GetInstance().UpdateColorMode(
339 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), themeMode);
340 pipeline->SetLocalColorMode(themeMode);
341 needRestore = true;
342 }
343 auto wrapper = builderIter->second(themeConstants_);
344 if (needRestore) {
345 // Switching resource manager back into system color mode
346 pipeline->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
347 ResourceManager::GetInstance().UpdateColorMode(
348 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), currentMode);
349 }
350 wrapper->ApplyTokenTheme(*tokenTheme);
351 themeWrappers.emplace(type, wrapper);
352 return AceType::DynamicCast<Theme>(wrapper);
353 }
354
GetThemeKit(ThemeType type,int32_t themeScopeId)355 RefPtr<Theme> ThemeManagerImpl::GetThemeKit(ThemeType type, int32_t themeScopeId)
356 {
357 auto tokenTheme = NG::TokenThemeStorage::GetInstance()->GetTheme(themeScopeId);
358 if (!tokenTheme) {
359 return GetTheme(type);
360 }
361
362 auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
363 CHECK_NULL_RETURN(pipeline, GetTheme(type));
364 ColorMode currentMode = GetCurrentColorMode();
365 ColorMode themeMode = tokenTheme->GetColorMode();
366 auto& themeWrappers = GetThemeWrappers(themeMode == ColorMode::COLOR_MODE_UNDEFINED ? currentMode : themeMode);
367 auto findIter = themeWrappers.find(type);
368 if (findIter != themeWrappers.end()) {
369 auto wrapper = findIter->second;
370 wrapper->ApplyTokenTheme(*tokenTheme);
371 return AceType::DynamicCast<Theme>(wrapper);
372 }
373
374 auto builderIter = TOKEN_THEME_WRAPPER_BUILDERS_KIT.find(type);
375 if (builderIter == TOKEN_THEME_WRAPPER_BUILDERS_KIT.end()) {
376 return nullptr;
377 }
378
379 bool needRestore = false;
380 if (themeMode != ColorMode::COLOR_MODE_UNDEFINED && themeMode != currentMode) {
381 // Local color mode of the current theme does not match actual color scheme.
382 // Current color mode is system. Need to switch to local color mode temporarily.
383 ResourceManager::GetInstance().UpdateColorMode(
384 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), themeMode);
385 pipeline->SetLocalColorMode(themeMode);
386 needRestore = true;
387 }
388 auto wrapper = builderIter->second();
389 if (needRestore) {
390 // Switching resource manager back into system color mode
391 pipeline->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED);
392 ResourceManager::GetInstance().UpdateColorMode(
393 pipeline->GetBundleName(), pipeline->GetModuleName(), pipeline->GetInstanceId(), currentMode);
394 }
395 wrapper->ApplyTokenTheme(*tokenTheme);
396 themeWrappers.emplace(type, wrapper);
397 return AceType::DynamicCast<Theme>(wrapper);
398 }
399
GetBackgroundColor() const400 Color ThemeManagerImpl::GetBackgroundColor() const
401 {
402 auto findIter = themes_.find(AppTheme::TypeId());
403 if (findIter != themes_.end()) {
404 auto appTheme = AceType::DynamicCast<AppTheme>(findIter->second);
405 if (appTheme) {
406 return appTheme->GetBackgroundColor();
407 }
408 }
409 // Parse attr from system theme style.
410 auto themeStyle = themeConstants_->GetThemeStyle();
411 auto prebuildColor = themeConstants_->GetColor(THEME_APP_BACKGROUND);
412 if (!themeStyle) {
413 return prebuildColor;
414 }
415 if (themeStyle->HasAttr(THEME_ATTR_BG_COLOR) && !themeConstants_->HasCustomStyle(THEME_APP_BACKGROUND)) {
416 // Get from resource.
417 return themeStyle->GetAttr<Color>(THEME_ATTR_BG_COLOR, Color::BLACK);
418 } else {
419 // Get from prebuild or custom color.
420 return prebuildColor;
421 }
422 }
423
LoadResourceThemes()424 void ThemeManagerImpl::LoadResourceThemes()
425 {
426 themes_.clear();
427 themeWrappersLight_.clear();
428 themeWrappersDark_.clear();
429 themeConstants_->LoadTheme(currentThemeId_);
430 }
431
GetThemeWrappers(ColorMode mode)432 ThemeManagerImpl::ThemeWrappers& ThemeManagerImpl::GetThemeWrappers(ColorMode mode)
433 {
434 return mode == ColorMode::DARK ? themeWrappersDark_ : themeWrappersLight_;
435 }
436
GetCurrentColorMode() const437 ColorMode ThemeManagerImpl::GetCurrentColorMode() const
438 {
439 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
440 ColorMode systemMode = Container::CurrentColorMode();
441 CHECK_NULL_RETURN(pipelineContext, systemMode);
442 ColorMode localMode = pipelineContext->GetLocalColorMode();
443 return localMode == ColorMode::COLOR_MODE_UNDEFINED ? systemMode : localMode;
444 }
445 } // namespace OHOS::Ace
446