Home | History | Annotate | Download | only in themes
      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 int GetDisplayProperty(int id) 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   // Uninstall theme extensions which are no longer in use. |ignore_infobars| is
    139   // whether unused themes should be removed despite a theme infobar being
    140   // visible.
    141   void RemoveUnusedThemes(bool ignore_infobars);
    142 
    143   // Returns the syncable service for syncing theme. The returned service is
    144   // owned by |this| object.
    145   virtual ThemeSyncableService* GetThemeSyncableService() const;
    146 
    147   // Save the images to be written to disk, mapping file path to id.
    148   typedef std::map<base::FilePath, int> ImagesDiskCache;
    149 
    150  protected:
    151   // Set a custom default theme instead of the normal default theme.
    152   virtual void SetCustomDefaultTheme(
    153       scoped_refptr<CustomThemeSupplier> theme_supplier);
    154 
    155   // Returns true if the ThemeService should use the native theme on startup.
    156   virtual bool ShouldInitWithNativeTheme() const;
    157 
    158   // Get the specified tint - |id| is one of the TINT_* enum values.
    159   color_utils::HSL GetTint(int id) const;
    160 
    161   // Clears all the override fields and saves the dictionary.
    162   virtual void ClearAllThemeData();
    163 
    164   // Load theme data from preferences.
    165   virtual void LoadThemePrefs();
    166 
    167   // Let all the browser views know that themes have changed.
    168   virtual void NotifyThemeChanged();
    169 
    170 #if defined(OS_MACOSX)
    171   // Let all the browser views know that themes have changed in a platform way.
    172   virtual void NotifyPlatformThemeChanged();
    173 #endif  // OS_MACOSX
    174 
    175   // Clears the platform-specific caches. Do not call directly; it's called
    176   // from ClearAllThemeData().
    177   virtual void FreePlatformCaches();
    178 
    179   Profile* profile() const { return profile_; }
    180 
    181   void set_ready() { ready_ = true; }
    182 
    183   const CustomThemeSupplier* get_theme_supplier() const {
    184     return theme_supplier_.get();
    185   }
    186 
    187   // True if the theme service is ready to be used.
    188   // TODO(pkotwicz): Add DCHECKS to the theme service's getters once
    189   // ThemeSource no longer uses the ThemeService when it is not ready.
    190   bool ready_;
    191 
    192  private:
    193   friend class theme_service_internal::ThemeServiceTest;
    194 
    195   // Called when the extension service is ready.
    196   void OnExtensionServiceReady();
    197 
    198   // Migrate the theme to the new theme pack schema by recreating the data pack
    199   // from the extension.
    200   void MigrateTheme();
    201 
    202   // Replaces the current theme supplier with a new one and calls
    203   // StopUsingTheme() or StartUsingTheme() as appropriate.
    204   void SwapThemeSupplier(scoped_refptr<CustomThemeSupplier> theme_supplier);
    205 
    206   // Saves the filename of the cached theme pack.
    207   void SavePackName(const base::FilePath& pack_path);
    208 
    209   // Save the id of the last theme installed.
    210   void SaveThemeID(const std::string& id);
    211 
    212   // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in
    213   // case we don't have a theme pack).
    214   void BuildFromExtension(const extensions::Extension* extension);
    215 
    216   // Returns true if the profile belongs to a managed user.
    217   bool IsManagedUser() const;
    218 
    219   // Sets the current theme to the managed user theme. Should only be used for
    220   // managed user profiles.
    221   void SetManagedUserTheme();
    222 
    223   // Sets the managed user theme if the user has no custom theme yet.
    224   void OnManagedUserInitialized();
    225 
    226 #if defined(TOOLKIT_GTK)
    227   // Loads an image and flips it horizontally if |rtl_enabled| is true.
    228   GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const;
    229 #endif
    230 
    231 #if defined(TOOLKIT_GTK)
    232   typedef std::map<int, GdkPixbuf*> GdkPixbufMap;
    233   mutable GdkPixbufMap gdk_pixbufs_;
    234 #elif defined(OS_MACOSX)
    235   // |nsimage_cache_| retains the images it has cached.
    236   typedef std::map<int, NSImage*> NSImageMap;
    237   mutable NSImageMap nsimage_cache_;
    238 
    239   // |nscolor_cache_| retains the colors it has cached.
    240   typedef std::map<int, NSColor*> NSColorMap;
    241   mutable NSColorMap nscolor_cache_;
    242 
    243   typedef std::map<int, NSGradient*> NSGradientMap;
    244   mutable NSGradientMap nsgradient_cache_;
    245 #endif
    246 
    247   ui::ResourceBundle& rb_;
    248   Profile* profile_;
    249 
    250   scoped_refptr<CustomThemeSupplier> theme_supplier_;
    251 
    252   // The id of the theme extension which has just been installed but has not
    253   // been loaded yet. The theme extension with |installed_pending_load_id_| may
    254   // never be loaded if the install is due to updating a disabled theme.
    255   // |pending_install_id_| should be set to |kDefaultThemeID| if there are no
    256   // recently installed theme extensions
    257   std::string installed_pending_load_id_;
    258 
    259   // The number of infobars currently displayed.
    260   int number_of_infobars_;
    261 
    262   content::NotificationRegistrar registrar_;
    263 
    264   scoped_ptr<ThemeSyncableService> theme_syncable_service_;
    265 
    266   base::WeakPtrFactory<ThemeService> weak_ptr_factory_;
    267 
    268   DISALLOW_COPY_AND_ASSIGN(ThemeService);
    269 };
    270 
    271 #endif  // CHROME_BROWSER_THEMES_THEME_SERVICE_H_
    272