1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_H_
6 #define CHROME_BROWSER_THEMES_THEME_SERVICE_H_
13 #include "base/compiler_specific.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/threading/non_thread_safe.h"
18 #include "components/keyed_service/core/keyed_service.h"
19 #include "content/public/browser/notification_observer.h"
20 #include "content/public/browser/notification_registrar.h"
21 #include "ui/base/theme_provider.h"
23 class CustomThemeSupplier;
24 class BrowserThemePack;
25 class ThemeSyncableService;
32 namespace color_utils {
36 namespace extensions {
44 namespace theme_service_internal {
45 class ThemeServiceTest;
54 // Sent whenever the browser theme changes. Object => NSValue wrapping the
55 // ThemeService that changed.
56 extern "C" NSString* const kBrowserThemeDidChangeNotification;
59 class ThemeService : public base::NonThreadSafe,
60 public content::NotificationObserver,
62 public ui::ThemeProvider {
64 // Public constants used in ThemeService and its subclasses:
65 static const char* kDefaultThemeID;
68 virtual ~ThemeService();
70 virtual void Init(Profile* profile);
72 // Returns a cross platform image for an id.
74 // TODO(erg): Make this part of the ui::ThemeProvider and the main way to get
75 // theme properties out of the theme provider since it's cross platform.
76 virtual gfx::Image GetImageNamed(int id) const;
78 // Overridden from ui::ThemeProvider:
79 virtual bool UsingNativeTheme() const OVERRIDE;
80 virtual gfx::ImageSkia* GetImageSkiaNamed(int id) const OVERRIDE;
81 virtual SkColor GetColor(int id) const OVERRIDE;
82 virtual int GetDisplayProperty(int id) const OVERRIDE;
83 virtual bool ShouldUseNativeFrame() const OVERRIDE;
84 virtual bool HasCustomImage(int id) const OVERRIDE;
85 virtual base::RefCountedMemory* GetRawData(
87 ui::ScaleFactor scale_factor) const OVERRIDE;
88 #if defined(OS_MACOSX)
89 virtual NSImage* GetNSImageNamed(int id) const OVERRIDE;
90 virtual NSColor* GetNSImageColorNamed(int id) const OVERRIDE;
91 virtual NSColor* GetNSColor(int id) const OVERRIDE;
92 virtual NSColor* GetNSColorTint(int id) const OVERRIDE;
93 virtual NSGradient* GetNSGradient(int id) const OVERRIDE;
94 #elif defined(OS_POSIX) && !defined(TOOLKIT_VIEWS) && !defined(OS_ANDROID)
95 // This mismatch between what this class defines and whether or not it
96 // overrides ui::ThemeProvider is http://crbug.com/105040 .
97 // GdkPixbufs returned by GetPixbufNamed and GetRTLEnabledPixbufNamed are
98 // shared instances owned by the theme provider and should not be freed.
99 virtual GdkPixbuf* GetRTLEnabledPixbufNamed(int id) const OVERRIDE;
102 // Overridden from content::NotificationObserver:
103 virtual void Observe(int type,
104 const content::NotificationSource& source,
105 const content::NotificationDetails& details) OVERRIDE;
107 // Set the current theme to the theme defined in |extension|.
108 // |extension| must already be added to this profile's
110 virtual void SetTheme(const extensions::Extension* extension);
112 // Reset the theme to default.
113 virtual void UseDefaultTheme();
115 // Set the current theme to the native theme. On some platforms, the native
116 // theme is the default theme.
117 virtual void SetNativeTheme();
119 // Whether we're using the chrome default theme. Virtual so linux can check
120 // if we're using the GTK theme.
121 virtual bool UsingDefaultTheme() const;
123 // Gets the id of the last installed theme. (The theme may have been further
124 // locally customized.)
125 virtual std::string GetThemeID() const;
127 // This class needs to keep track of the number of theme infobars so that we
128 // clean up unused themes.
129 void OnInfobarDisplayed();
131 // Decrements the number of theme infobars. If the last infobar has been
132 // destroyed, uninstalls all themes that aren't the currently selected.
133 void OnInfobarDestroyed();
135 // Uninstall theme extensions which are no longer in use. |ignore_infobars| is
136 // whether unused themes should be removed despite a theme infobar being
138 void RemoveUnusedThemes(bool ignore_infobars);
140 // Returns the syncable service for syncing theme. The returned service is
141 // owned by |this| object.
142 virtual ThemeSyncableService* GetThemeSyncableService() const;
144 // Save the images to be written to disk, mapping file path to id.
145 typedef std::map<base::FilePath, int> ImagesDiskCache;
148 // Set a custom default theme instead of the normal default theme.
149 virtual void SetCustomDefaultTheme(
150 scoped_refptr<CustomThemeSupplier> theme_supplier);
152 // Returns true if the ThemeService should use the native theme on startup.
153 virtual bool ShouldInitWithNativeTheme() const;
155 // Get the specified tint - |id| is one of the TINT_* enum values.
156 color_utils::HSL GetTint(int id) const;
158 // Clears all the override fields and saves the dictionary.
159 virtual void ClearAllThemeData();
161 // Load theme data from preferences.
162 virtual void LoadThemePrefs();
164 // Let all the browser views know that themes have changed.
165 virtual void NotifyThemeChanged();
167 #if defined(OS_MACOSX)
168 // Let all the browser views know that themes have changed in a platform way.
169 virtual void NotifyPlatformThemeChanged();
172 // Clears the platform-specific caches. Do not call directly; it's called
173 // from ClearAllThemeData().
174 virtual void FreePlatformCaches();
176 Profile* profile() const { return profile_; }
178 void set_ready() { ready_ = true; }
180 const CustomThemeSupplier* get_theme_supplier() const {
181 return theme_supplier_.get();
184 // True if the theme service is ready to be used.
185 // TODO(pkotwicz): Add DCHECKS to the theme service's getters once
186 // ThemeSource no longer uses the ThemeService when it is not ready.
190 friend class theme_service_internal::ThemeServiceTest;
192 // Called when the extension service is ready.
193 void OnExtensionServiceReady();
195 // Migrate the theme to the new theme pack schema by recreating the data pack
196 // from the extension.
199 // Replaces the current theme supplier with a new one and calls
200 // StopUsingTheme() or StartUsingTheme() as appropriate.
201 void SwapThemeSupplier(scoped_refptr<CustomThemeSupplier> theme_supplier);
203 // Saves the filename of the cached theme pack.
204 void SavePackName(const base::FilePath& pack_path);
206 // Save the id of the last theme installed.
207 void SaveThemeID(const std::string& id);
209 // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in
210 // case we don't have a theme pack).
211 void BuildFromExtension(const extensions::Extension* extension);
213 // Returns true if the profile belongs to a managed user.
214 bool IsManagedUser() const;
216 // Sets the current theme to the managed user theme. Should only be used for
217 // managed user profiles.
218 void SetManagedUserTheme();
220 // Sets the managed user theme if the user has no custom theme yet.
221 void OnManagedUserInitialized();
223 #if defined(TOOLKIT_GTK)
224 // Loads an image and flips it horizontally if |rtl_enabled| is true.
225 GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const;
228 #if defined(TOOLKIT_GTK)
229 typedef std::map<int, GdkPixbuf*> GdkPixbufMap;
230 mutable GdkPixbufMap gdk_pixbufs_;
231 #elif defined(OS_MACOSX)
232 // |nsimage_cache_| retains the images it has cached.
233 typedef std::map<int, NSImage*> NSImageMap;
234 mutable NSImageMap nsimage_cache_;
236 // |nscolor_cache_| retains the colors it has cached.
237 typedef std::map<int, NSColor*> NSColorMap;
238 mutable NSColorMap nscolor_cache_;
240 typedef std::map<int, NSGradient*> NSGradientMap;
241 mutable NSGradientMap nsgradient_cache_;
244 ui::ResourceBundle& rb_;
247 scoped_refptr<CustomThemeSupplier> theme_supplier_;
249 // The id of the theme extension which has just been installed but has not
250 // been loaded yet. The theme extension with |installed_pending_load_id_| may
251 // never be loaded if the install is due to updating a disabled theme.
252 // |pending_install_id_| should be set to |kDefaultThemeID| if there are no
253 // recently installed theme extensions
254 std::string installed_pending_load_id_;
256 // The number of infobars currently displayed.
257 int number_of_infobars_;
259 content::NotificationRegistrar registrar_;
261 scoped_ptr<ThemeSyncableService> theme_syncable_service_;
263 base::WeakPtrFactory<ThemeService> weak_ptr_factory_;
265 DISALLOW_COPY_AND_ASSIGN(ThemeService);
268 #endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_