1 // Copyright (c) 2011 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 #pragma once 8 9 #include <map> 10 #include <set> 11 #include <string> 12 13 #include "base/memory/ref_counted.h" 14 #include "base/threading/non_thread_safe.h" 15 #include "chrome/browser/profiles/profile_keyed_service.h" 16 #include "content/common/notification_observer.h" 17 #include "content/common/notification_registrar.h" 18 #include "ui/base/theme_provider.h" 19 20 class BrowserThemePack; 21 class ThemeServiceTest; 22 class Extension; 23 class FilePath; 24 class Profile; 25 26 namespace color_utils { 27 struct HSL; 28 } 29 30 namespace ui { 31 class ResourceBundle; 32 } 33 using ui::ResourceBundle; 34 35 #ifdef __OBJC__ 36 @class NSString; 37 // Sent whenever the browser theme changes. Object => NSValue wrapping the 38 // ThemeService that changed. 39 extern "C" NSString* const kBrowserThemeDidChangeNotification; 40 #endif // __OBJC__ 41 42 class ThemeService : public base::NonThreadSafe, 43 public NotificationObserver, 44 public ProfileKeyedService, 45 public ui::ThemeProvider { 46 public: 47 // Public constants used in ThemeService and its subclasses: 48 49 // Strings used in alignment properties. 50 static const char* kAlignmentTop; 51 static const char* kAlignmentBottom; 52 static const char* kAlignmentLeft; 53 static const char* kAlignmentRight; 54 55 // Strings used in tiling properties. 56 static const char* kTilingNoRepeat; 57 static const char* kTilingRepeatX; 58 static const char* kTilingRepeatY; 59 static const char* kTilingRepeat; 60 61 static const char* kDefaultThemeID; 62 63 // Returns true if the image is themeable. Safe to call on any thread. 64 static bool IsThemeableImage(int resource_id); 65 66 ThemeService(); 67 virtual ~ThemeService(); 68 69 enum { 70 COLOR_FRAME, 71 COLOR_FRAME_INACTIVE, 72 COLOR_FRAME_INCOGNITO, 73 COLOR_FRAME_INCOGNITO_INACTIVE, 74 COLOR_TOOLBAR, 75 COLOR_TAB_TEXT, 76 COLOR_BACKGROUND_TAB_TEXT, 77 COLOR_BOOKMARK_TEXT, 78 COLOR_NTP_BACKGROUND, 79 COLOR_NTP_TEXT, 80 COLOR_NTP_LINK, 81 COLOR_NTP_LINK_UNDERLINE, 82 COLOR_NTP_HEADER, 83 COLOR_NTP_SECTION, 84 COLOR_NTP_SECTION_TEXT, 85 COLOR_NTP_SECTION_LINK, 86 COLOR_NTP_SECTION_LINK_UNDERLINE, 87 COLOR_CONTROL_BACKGROUND, 88 COLOR_BUTTON_BACKGROUND, 89 90 // These colors don't have constant default values. They are derived from 91 // the runtime value of other colors. 92 COLOR_NTP_SECTION_HEADER_TEXT, 93 COLOR_NTP_SECTION_HEADER_TEXT_HOVER, 94 COLOR_NTP_SECTION_HEADER_RULE, 95 COLOR_NTP_SECTION_HEADER_RULE_LIGHT, 96 COLOR_NTP_TEXT_LIGHT, 97 98 TINT_BUTTONS, 99 TINT_FRAME, 100 TINT_FRAME_INACTIVE, 101 TINT_FRAME_INCOGNITO, 102 TINT_FRAME_INCOGNITO_INACTIVE, 103 TINT_BACKGROUND_TAB, 104 NTP_BACKGROUND_ALIGNMENT, 105 NTP_BACKGROUND_TILING, 106 NTP_LOGO_ALTERNATE 107 #if defined(OS_MACOSX) 108 , 109 COLOR_TOOLBAR_BEZEL = 1000, 110 COLOR_TOOLBAR_STROKE, 111 COLOR_TOOLBAR_STROKE_INACTIVE, 112 COLOR_TOOLBAR_BUTTON_STROKE, 113 COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, 114 GRADIENT_FRAME_INCOGNITO, 115 GRADIENT_FRAME_INCOGNITO_INACTIVE, 116 GRADIENT_TOOLBAR, 117 GRADIENT_TOOLBAR_INACTIVE, 118 GRADIENT_TOOLBAR_BUTTON, 119 GRADIENT_TOOLBAR_BUTTON_INACTIVE, 120 GRADIENT_TOOLBAR_BUTTON_PRESSED, 121 GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE 122 #endif // OS_MACOSX 123 }; 124 125 // A bitfield mask for alignments. 126 typedef enum { 127 ALIGN_CENTER = 0x0, 128 ALIGN_LEFT = 0x1, 129 ALIGN_TOP = 0x2, 130 ALIGN_RIGHT = 0x4, 131 ALIGN_BOTTOM = 0x8, 132 } AlignmentMasks; 133 134 // Background tiling choices. 135 typedef enum { 136 NO_REPEAT = 0, 137 REPEAT_X = 1, 138 REPEAT_Y = 2, 139 REPEAT = 3 140 } Tiling; 141 142 // ui::ThemeProvider implementation. 143 virtual void Init(Profile* profile); 144 virtual SkBitmap* GetBitmapNamed(int id) const; 145 virtual SkColor GetColor(int id) const; 146 virtual bool GetDisplayProperty(int id, int* result) const; 147 virtual bool ShouldUseNativeFrame() const; 148 virtual bool HasCustomImage(int id) const; 149 virtual RefCountedMemory* GetRawData(int id) const; 150 #if defined(TOOLKIT_USES_GTK) 151 // GdkPixbufs returned by GetPixbufNamed and GetRTLEnabledPixbufNamed are 152 // shared instances owned by the theme provider and should not be freed. 153 virtual GdkPixbuf* GetPixbufNamed(int id) const; 154 virtual GdkPixbuf* GetRTLEnabledPixbufNamed(int id) const; 155 #elif defined(OS_MACOSX) 156 virtual NSImage* GetNSImageNamed(int id, bool allow_default) const; 157 virtual NSColor* GetNSImageColorNamed(int id, bool allow_default) const; 158 virtual NSColor* GetNSColor(int id, bool allow_default) const; 159 virtual NSColor* GetNSColorTint(int id, bool allow_default) const; 160 virtual NSGradient* GetNSGradient(int id) const; 161 #endif 162 163 // Set the current theme to the theme defined in |extension|. 164 virtual void SetTheme(const Extension* extension); 165 166 // Reset the theme to default. 167 virtual void UseDefaultTheme(); 168 169 // Set the current theme to the native theme. On some platforms, the native 170 // theme is the default theme. 171 virtual void SetNativeTheme(); 172 173 // Whether we're using the chrome default theme. Virtual so linux can check 174 // if we're using the GTK theme. 175 virtual bool UsingDefaultTheme(); 176 177 // Gets the id of the last installed theme. (The theme may have been further 178 // locally customized.) 179 virtual std::string GetThemeID() const; 180 181 // This class needs to keep track of the number of theme infobars so that we 182 // clean up unused themes. 183 void OnInfobarDisplayed(); 184 185 // Decrements the number of theme infobars. If the last infobar has been 186 // destroyed, uninstalls all themes that aren't the currently selected. 187 void OnInfobarDestroyed(); 188 189 // Convert a bitfield alignment into a string like "top left". Public so that 190 // it can be used to generate CSS values. Takes a bitfield of AlignmentMasks. 191 static std::string AlignmentToString(int alignment); 192 193 // Parse alignments from something like "top left" into a bitfield of 194 // AlignmentMasks 195 static int StringToAlignment(const std::string& alignment); 196 197 // Convert a tiling value into a string like "no-repeat". Public 198 // so that it can be used to generate CSS values. Takes a Tiling. 199 static std::string TilingToString(int tiling); 200 201 // Parse tiling values from something like "no-repeat" into a Tiling value. 202 static int StringToTiling(const std::string& tiling); 203 204 // Returns the default tint for the given tint |id| TINT_* enum value. 205 static color_utils::HSL GetDefaultTint(int id); 206 207 // Returns the default color for the given color |id| COLOR_* enum value. 208 static SkColor GetDefaultColor(int id); 209 210 // Returns true and sets |result| to the requested default property, if |id| 211 // is valid. 212 static bool GetDefaultDisplayProperty(int id, int* result); 213 214 // Returns the set of IDR_* resources that should be tinted. 215 static const std::set<int>& GetTintableToolbarButtons(); 216 217 // Remove preference values for themes that are no longer in use. 218 void RemoveUnusedThemes(); 219 220 // Save the images to be written to disk, mapping file path to id. 221 typedef std::map<FilePath, int> ImagesDiskCache; 222 223 protected: 224 // Get the specified tint - |id| is one of the TINT_* enum values. 225 color_utils::HSL GetTint(int id) const; 226 227 // Clears all the override fields and saves the dictionary. 228 virtual void ClearAllThemeData(); 229 230 // Load theme data from preferences. 231 virtual void LoadThemePrefs(); 232 233 // Let all the browser views know that themes have changed. 234 virtual void NotifyThemeChanged(); 235 236 #if defined(OS_MACOSX) 237 // Let all the browser views know that themes have changed in a platform way. 238 virtual void NotifyPlatformThemeChanged(); 239 #endif // OS_MACOSX 240 241 // Clears the platform-specific caches. Do not call directly; it's called 242 // from ClearCaches(). 243 virtual void FreePlatformCaches(); 244 245 Profile* profile() { return profile_; } 246 247 // NotificationObserver: 248 virtual void Observe(NotificationType type, 249 const NotificationSource& source, 250 const NotificationDetails& details); 251 252 private: 253 friend class ThemeServiceTest; 254 255 // Saves the filename of the cached theme pack. 256 void SavePackName(const FilePath& pack_path); 257 258 // Save the id of the last theme installed. 259 void SaveThemeID(const std::string& id); 260 261 // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in 262 // case we don't have a theme pack). 263 void BuildFromExtension(const Extension* extension); 264 265 #if defined(TOOLKIT_USES_GTK) 266 // Loads an image and flips it horizontally if |rtl_enabled| is true. 267 GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const; 268 #endif 269 270 #if defined(TOOLKIT_USES_GTK) 271 typedef std::map<int, GdkPixbuf*> GdkPixbufMap; 272 mutable GdkPixbufMap gdk_pixbufs_; 273 #elif defined(OS_MACOSX) 274 typedef std::map<int, NSImage*> NSImageMap; 275 mutable NSImageMap nsimage_cache_; 276 277 // The bool member of the pair is whether the color is a default color. 278 typedef std::map<int, std::pair<NSColor*, bool> > NSColorMap; 279 mutable NSColorMap nscolor_cache_; 280 281 typedef std::map<int, NSGradient*> NSGradientMap; 282 mutable NSGradientMap nsgradient_cache_; 283 #endif 284 285 ResourceBundle& rb_; 286 Profile* profile_; 287 288 scoped_refptr<BrowserThemePack> theme_pack_; 289 290 // The number of infobars currently displayed. 291 int number_of_infobars_; 292 293 NotificationRegistrar registrar_; 294 295 DISALLOW_COPY_AND_ASSIGN(ThemeService); 296 }; 297 298 #endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_ 299