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/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" 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 KeyedService, 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 bool UsingSystemTheme() 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( 86 int id, 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 #endif 95 96 // Overridden from content::NotificationObserver: 97 virtual void Observe(int type, 98 const content::NotificationSource& source, 99 const content::NotificationDetails& details) OVERRIDE; 100 101 // Set the current theme to the theme defined in |extension|. 102 // |extension| must already be added to this profile's 103 // ExtensionService. 104 virtual void SetTheme(const extensions::Extension* extension); 105 106 // Reset the theme to default. 107 virtual void UseDefaultTheme(); 108 109 // Set the current theme to the system theme. On some platforms, the system 110 // theme is the default theme. 111 virtual void UseSystemTheme(); 112 113 // Whether we're using the chrome default theme. Virtual so linux can check 114 // if we're using the GTK theme. 115 virtual bool UsingDefaultTheme() const; 116 117 // Gets the id of the last installed theme. (The theme may have been further 118 // locally customized.) 119 virtual std::string GetThemeID() const; 120 121 // This class needs to keep track of the number of theme infobars so that we 122 // clean up unused themes. 123 void OnInfobarDisplayed(); 124 125 // Decrements the number of theme infobars. If the last infobar has been 126 // destroyed, uninstalls all themes that aren't the currently selected. 127 void OnInfobarDestroyed(); 128 129 // Uninstall theme extensions which are no longer in use. |ignore_infobars| is 130 // whether unused themes should be removed despite a theme infobar being 131 // visible. 132 void RemoveUnusedThemes(bool ignore_infobars); 133 134 // Returns the syncable service for syncing theme. The returned service is 135 // owned by |this| object. 136 virtual ThemeSyncableService* GetThemeSyncableService() const; 137 138 // Save the images to be written to disk, mapping file path to id. 139 typedef std::map<base::FilePath, int> ImagesDiskCache; 140 141 protected: 142 // Set a custom default theme instead of the normal default theme. 143 virtual void SetCustomDefaultTheme( 144 scoped_refptr<CustomThemeSupplier> theme_supplier); 145 146 // Returns true if the ThemeService should use the system theme on startup. 147 virtual bool ShouldInitWithSystemTheme() const; 148 149 // Get the specified tint - |id| is one of the TINT_* enum values. 150 color_utils::HSL GetTint(int id) const; 151 152 // Clears all the override fields and saves the dictionary. 153 virtual void ClearAllThemeData(); 154 155 // Load theme data from preferences. 156 virtual void LoadThemePrefs(); 157 158 // Let all the browser views know that themes have changed. 159 virtual void NotifyThemeChanged(); 160 161 #if defined(OS_MACOSX) 162 // Let all the browser views know that themes have changed in a platform way. 163 virtual void NotifyPlatformThemeChanged(); 164 #endif // OS_MACOSX 165 166 // Clears the platform-specific caches. Do not call directly; it's called 167 // from ClearAllThemeData(). 168 virtual void FreePlatformCaches(); 169 170 Profile* profile() const { return profile_; } 171 172 void set_ready() { ready_ = true; } 173 174 const CustomThemeSupplier* get_theme_supplier() const { 175 return theme_supplier_.get(); 176 } 177 178 // True if the theme service is ready to be used. 179 // TODO(pkotwicz): Add DCHECKS to the theme service's getters once 180 // ThemeSource no longer uses the ThemeService when it is not ready. 181 bool ready_; 182 183 private: 184 friend class theme_service_internal::ThemeServiceTest; 185 186 // Called when the extension service is ready. 187 void OnExtensionServiceReady(); 188 189 // Migrate the theme to the new theme pack schema by recreating the data pack 190 // from the extension. 191 void MigrateTheme(); 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 // Saves the filename of the cached theme pack. 198 void SavePackName(const base::FilePath& pack_path); 199 200 // Save the id of the last theme installed. 201 void SaveThemeID(const std::string& id); 202 203 // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in 204 // case we don't have a theme pack). 205 void BuildFromExtension(const extensions::Extension* extension); 206 207 // Returns true if the profile belongs to a supervised user. 208 bool IsSupervisedUser() const; 209 210 // Sets the current theme to the supervised user theme. Should only be used 211 // for supervised user profiles. 212 void SetSupervisedUserTheme(); 213 214 #if defined(OS_MACOSX) 215 // |nsimage_cache_| retains the images it has cached. 216 typedef std::map<int, NSImage*> NSImageMap; 217 mutable NSImageMap nsimage_cache_; 218 219 // |nscolor_cache_| retains the colors it has cached. 220 typedef std::map<int, NSColor*> NSColorMap; 221 mutable NSColorMap nscolor_cache_; 222 223 typedef std::map<int, NSGradient*> NSGradientMap; 224 mutable NSGradientMap nsgradient_cache_; 225 #endif 226 227 ui::ResourceBundle& rb_; 228 Profile* profile_; 229 230 scoped_refptr<CustomThemeSupplier> theme_supplier_; 231 232 // The id of the theme extension which has just been installed but has not 233 // been loaded yet. The theme extension with |installed_pending_load_id_| may 234 // never be loaded if the install is due to updating a disabled theme. 235 // |pending_install_id_| should be set to |kDefaultThemeID| if there are no 236 // recently installed theme extensions 237 std::string installed_pending_load_id_; 238 239 // The number of infobars currently displayed. 240 int number_of_infobars_; 241 242 content::NotificationRegistrar registrar_; 243 244 scoped_ptr<ThemeSyncableService> theme_syncable_service_; 245 246 base::WeakPtrFactory<ThemeService> weak_ptr_factory_; 247 248 DISALLOW_COPY_AND_ASSIGN(ThemeService); 249 }; 250 251 #endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_ 252