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. 4 5 #ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_H_ 6 #define CHROME_BROWSER_THEMES_THEME_SERVICE_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 #include <utility> 12 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/browser_context_keyed_service/browser_context_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" 22 23 class CustomThemeSupplier; 24 class BrowserThemePack; 25 class ThemeSyncableService; 26 class Profile; 27 28 namespace base { 29 class FilePath; 30 } 31 32 namespace color_utils { 33 struct HSL; 34 } 35 36 namespace extensions { 37 class Extension; 38 } 39 40 namespace gfx { 41 class Image; 42 } 43 44 namespace theme_service_internal { 45 class ThemeServiceTest; 46 } 47 48 namespace ui { 49 class ResourceBundle; 50 } 51 52 #ifdef __OBJC__ 53 @class NSString; 54 // Sent whenever the browser theme changes. Object => NSValue wrapping the 55 // ThemeService that changed. 56 extern "C" NSString* const kBrowserThemeDidChangeNotification; 57 #endif // __OBJC__ 58 59 class ThemeService : public base::NonThreadSafe, 60 public content::NotificationObserver, 61 public BrowserContextKeyedService, 62 public ui::ThemeProvider { 63 public: 64 // Public constants used in ThemeService and its subclasses: 65 static const char* kDefaultThemeID; 66 67 ThemeService(); 68 virtual ~ThemeService(); 69 70 virtual void Init(Profile* profile); 71 72 // Returns a cross platform image for an id. 73 // 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; 77 78 // Overridden from ui::ThemeProvider: 79 virtual gfx::ImageSkia* GetImageSkiaNamed(int id) const OVERRIDE; 80 virtual SkColor GetColor(int id) const OVERRIDE; 81 virtual bool GetDisplayProperty(int id, int* result) const OVERRIDE; 82 virtual bool ShouldUseNativeFrame() const OVERRIDE; 83 virtual bool HasCustomImage(int id) const OVERRIDE; 84 virtual base::RefCountedMemory* GetRawData( 85 int id, 86 ui::ScaleFactor scale_factor) const OVERRIDE; 87 #if defined(OS_MACOSX) 88 virtual NSImage* GetNSImageNamed(int id) const OVERRIDE; 89 virtual NSColor* GetNSImageColorNamed(int id) const OVERRIDE; 90 virtual NSColor* GetNSColor(int id) const OVERRIDE; 91 virtual NSColor* GetNSColorTint(int id) const OVERRIDE; 92 virtual NSGradient* GetNSGradient(int id) const OVERRIDE; 93 #elif defined(OS_POSIX) && !defined(TOOLKIT_VIEWS) && !defined(OS_ANDROID) 94 // This mismatch between what this class defines and whether or not it 95 // overrides ui::ThemeProvider is http://crbug.com/105040 . 96 // GdkPixbufs returned by GetPixbufNamed and GetRTLEnabledPixbufNamed are 97 // shared instances owned by the theme provider and should not be freed. 98 virtual GdkPixbuf* GetRTLEnabledPixbufNamed(int id) const OVERRIDE; 99 #endif 100 101 // Overridden from content::NotificationObserver: 102 virtual void Observe(int type, 103 const content::NotificationSource& source, 104 const content::NotificationDetails& details) OVERRIDE; 105 106 // Set the current theme to the theme defined in |extension|. 107 // |extension| must already be added to this profile's 108 // ExtensionService. 109 virtual void SetTheme(const extensions::Extension* extension); 110 111 // Reset the theme to default. 112 virtual void UseDefaultTheme(); 113 114 // Set the current theme to the native theme. On some platforms, the native 115 // theme is the default theme. 116 virtual void SetNativeTheme(); 117 118 // Whether we're using the chrome default theme. Virtual so linux can check 119 // if we're using the GTK theme. 120 virtual bool UsingDefaultTheme() const; 121 122 // Whether we're using the native theme (which may or may not be the 123 // same as the default theme). 124 virtual bool UsingNativeTheme() const; 125 126 // Gets the id of the last installed theme. (The theme may have been further 127 // locally customized.) 128 virtual std::string GetThemeID() const; 129 130 // This class needs to keep track of the number of theme infobars so that we 131 // clean up unused themes. 132 void OnInfobarDisplayed(); 133 134 // Decrements the number of theme infobars. If the last infobar has been 135 // destroyed, uninstalls all themes that aren't the currently selected. 136 void OnInfobarDestroyed(); 137 138 // Remove preference values for themes that are no longer in use. 139 void RemoveUnusedThemes(); 140 141 // Returns the syncable service for syncing theme. The returned service is 142 // owned by |this| object. 143 virtual ThemeSyncableService* GetThemeSyncableService() const; 144 145 // Save the images to be written to disk, mapping file path to id. 146 typedef std::map<base::FilePath, int> ImagesDiskCache; 147 148 protected: 149 // Set a custom default theme instead of the normal default theme. 150 virtual void SetCustomDefaultTheme( 151 scoped_refptr<CustomThemeSupplier> theme_supplier); 152 153 // Returns true if the ThemeService should use the native theme on startup. 154 virtual bool ShouldInitWithNativeTheme() const; 155 156 // Get the specified tint - |id| is one of the TINT_* enum values. 157 color_utils::HSL GetTint(int id) const; 158 159 // Clears all the override fields and saves the dictionary. 160 virtual void ClearAllThemeData(); 161 162 // Load theme data from preferences. 163 virtual void LoadThemePrefs(); 164 165 // Let all the browser views know that themes have changed. 166 virtual void NotifyThemeChanged(); 167 168 #if defined(OS_MACOSX) 169 // Let all the browser views know that themes have changed in a platform way. 170 virtual void NotifyPlatformThemeChanged(); 171 #endif // OS_MACOSX 172 173 // Clears the platform-specific caches. Do not call directly; it's called 174 // from ClearAllThemeData(). 175 virtual void FreePlatformCaches(); 176 177 Profile* profile() const { return profile_; } 178 179 void set_ready() { ready_ = true; } 180 181 const CustomThemeSupplier* get_theme_supplier() const { 182 return theme_supplier_.get(); 183 } 184 185 // True if the theme service is ready to be used. 186 // TODO(pkotwicz): Add DCHECKS to the theme service's getters once 187 // ThemeSource no longer uses the ThemeService when it is not ready. 188 bool ready_; 189 190 private: 191 friend class theme_service_internal::ThemeServiceTest; 192 193 // Replaces the current theme supplier with a new one and calls 194 // StopUsingTheme() or StartUsingTheme() as appropriate. 195 void SwapThemeSupplier(scoped_refptr<CustomThemeSupplier> theme_supplier); 196 197 // Migrate the theme to the new theme pack schema by recreating the data pack 198 // from the extension. 199 void MigrateTheme(); 200 201 // Saves the filename of the cached theme pack. 202 void SavePackName(const base::FilePath& pack_path); 203 204 // Save the id of the last theme installed. 205 void SaveThemeID(const std::string& id); 206 207 // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in 208 // case we don't have a theme pack). 209 void BuildFromExtension(const extensions::Extension* extension); 210 211 // Returns true if the profile belongs to a managed user. 212 bool IsManagedUser() const; 213 214 // Sets the current theme to the managed user theme. Should only be used for 215 // managed user profiles. 216 void SetManagedUserTheme(); 217 218 // Sets the managed user theme if the user has no custom theme yet. 219 void OnManagedUserInitialized(); 220 221 #if defined(TOOLKIT_GTK) 222 // Loads an image and flips it horizontally if |rtl_enabled| is true. 223 GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const; 224 #endif 225 226 #if defined(TOOLKIT_GTK) 227 typedef std::map<int, GdkPixbuf*> GdkPixbufMap; 228 mutable GdkPixbufMap gdk_pixbufs_; 229 #elif defined(OS_MACOSX) 230 // |nsimage_cache_| retains the images it has cached. 231 typedef std::map<int, NSImage*> NSImageMap; 232 mutable NSImageMap nsimage_cache_; 233 234 // |nscolor_cache_| retains the colors it has cached. 235 typedef std::map<int, NSColor*> NSColorMap; 236 mutable NSColorMap nscolor_cache_; 237 238 typedef std::map<int, NSGradient*> NSGradientMap; 239 mutable NSGradientMap nsgradient_cache_; 240 #endif 241 242 ui::ResourceBundle& rb_; 243 Profile* profile_; 244 245 scoped_refptr<CustomThemeSupplier> theme_supplier_; 246 247 // The number of infobars currently displayed. 248 int number_of_infobars_; 249 250 content::NotificationRegistrar registrar_; 251 252 scoped_ptr<ThemeSyncableService> theme_syncable_service_; 253 254 base::WeakPtrFactory<ThemeService> weak_ptr_factory_; 255 256 DISALLOW_COPY_AND_ASSIGN(ThemeService); 257 }; 258 259 #endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_ 260