• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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