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