diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-22 18:05:22 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-22 18:05:22 +0000 |
commit | 18280378d78cc83d8e83de21f28411cb4fa777bc (patch) | |
tree | a820592ddb8899a850e75061fc2e4e533e8b149e /chrome/browser/themes | |
parent | 33a85f181bf099afe9067d50277ea0e85e35f302 (diff) | |
download | chromium_src-18280378d78cc83d8e83de21f28411cb4fa777bc.zip chromium_src-18280378d78cc83d8e83de21f28411cb4fa777bc.tar.gz chromium_src-18280378d78cc83d8e83de21f28411cb4fa777bc.tar.bz2 |
Profile shouldn't own BrowserThemeProviders; A ThemeService should and should give back a BTP when presented with a Profile.
This removes all Profile methods that deal with themes. A profile is now just the key that ThemeService maps to a BrowserThemeProvider. Any user of a BrowserThemeProvider asks ThemeService::GetForProfile() instead of the now deleted Profile::GetThemeProvider() method.
Why do this? Because this will drastically reduce coupling. Right now, the Profile knows about pretty much every major object in chrome/browser/. This should allow easier compile time removal of certain systems.
BUG=profile effort
TEST=existing tests
Review URL: http://codereview.chromium.org/6714003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79001 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/themes')
-rw-r--r-- | chrome/browser/themes/browser_theme_provider.h | 4 | ||||
-rw-r--r-- | chrome/browser/themes/theme_service.cc | 109 | ||||
-rw-r--r-- | chrome/browser/themes/theme_service.h | 59 |
3 files changed, 170 insertions, 2 deletions
diff --git a/chrome/browser/themes/browser_theme_provider.h b/chrome/browser/themes/browser_theme_provider.h index fe65a7d..92a5c57 100644 --- a/chrome/browser/themes/browser_theme_provider.h +++ b/chrome/browser/themes/browser_theme_provider.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -171,7 +171,7 @@ class BrowserThemeProvider : public base::NonThreadSafe, // Gets the id of the last installed theme. (The theme may have been further // locally customized.) - std::string GetThemeID() const; + virtual std::string GetThemeID() const; // This class needs to keep track of the number of theme infobars so that we // clean up unused themes. diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc new file mode 100644 index 0000000..eae2b76 --- /dev/null +++ b/chrome/browser/themes/theme_service.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/theme_service.h" + +#include "base/logging.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "content/common/notification_service.h" + +#if defined(TOOLKIT_USES_GTK) +#include "chrome/browser/ui/gtk/gtk_theme_provider.h" +#endif + +// static +BrowserThemeProvider* ThemeServiceFactory::GetForProfile(Profile* top_profile) { + // We may be asked for the Theme of an incognito profile. Make sure we're + // operating on the real profile. + Profile* profile = top_profile->GetOriginalProfile(); + + ThemeServiceFactory* service = GetInstance(); + + std::map<Profile*, BrowserThemeProvider*>::const_iterator it = + service->mapping_.find(profile); + if (it != service->mapping_.end()) + return it->second; + + BrowserThemeProvider* provider = NULL; +#if defined(TOOLKIT_USES_GTK) + provider = new GtkThemeProvider; +#else + provider = new BrowserThemeProvider; +#endif + provider->Init(profile); + + service->Associate(profile, provider); + return provider; +} + +const Extension* ThemeServiceFactory::GetThemeForProfile(Profile* profile) { + std::string id = GetForProfile(profile)->GetThemeID(); + if (id == BrowserThemeProvider::kDefaultThemeID) + return NULL; + + return profile->GetExtensionService()->GetExtensionById(id, false); +} + +void ThemeServiceFactory::ForceAssociationBetween(Profile* top_profile, + BrowserThemeProvider* provider) { + ThemeServiceFactory* service = GetInstance(); + Profile* profile = top_profile->GetOriginalProfile(); + + service->Associate(profile, provider); +} + +ThemeServiceFactory* ThemeServiceFactory::GetInstance() { + return Singleton<ThemeServiceFactory>::get(); +} + +ThemeServiceFactory::ThemeServiceFactory() {} + +ThemeServiceFactory::~ThemeServiceFactory() { + DCHECK(mapping_.empty()); +} + +void ThemeServiceFactory::Associate(Profile* profile, + BrowserThemeProvider* provider) { + DCHECK(mapping_.find(profile) == mapping_.end()); + mapping_.insert(std::make_pair(profile, provider)); + + registrar_.Add(this, + NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile)); + registrar_.Add(this, + NotificationType::THEME_INSTALLED, + Source<Profile>(profile)); +} + +void ThemeServiceFactory::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + std::map<Profile*, BrowserThemeProvider*>::iterator it = + mapping_.find(Source<Profile>(source).ptr()); + DCHECK(it != mapping_.end()); + + if (NotificationType::PROFILE_DESTROYED == type) { + delete it->second; + mapping_.erase(it); + + // Remove ourselves from listening to all notifications because the source + // profile has been deleted. We have to do this because several unit tests + // are set up so a Profile is on the same place on the stack multiple + // times, so while they are different instances, they have the same + // addresses. + registrar_.Remove(this, + NotificationType::PROFILE_DESTROYED, + source); + registrar_.Remove(this, + NotificationType::THEME_INSTALLED, + source); + } else if (NotificationType::THEME_INSTALLED == type) { + const Extension* extension = Details<const Extension>(details).ptr(); + it->second->SetTheme(extension); + } else { + NOTREACHED(); + } +} diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h new file mode 100644 index 0000000..44abcc2 --- /dev/null +++ b/chrome/browser/themes/theme_service.h @@ -0,0 +1,59 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_H_ +#define CHROME_BROWSER_THEMES_THEME_SERVICE_H_ + +#include <map> + +#include "base/singleton.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" + +class BrowserThemeProvider; +class Extension; +class Profile; + +// Singleton that owns all BrowserThemeProviders and associates them with +// Profiles. Listens for the Profile's destruction notification and cleans up +// the associated BrowserThemeProvider. +class ThemeServiceFactory : public NotificationObserver { + public: + // Returns the BrowserThemeProvider that provides theming resources for + // |profile|. Note that even if a Profile doesn't have a theme installed, it + // still needs a BrowserThemeProvider to hand back the default theme images. + static BrowserThemeProvider* GetForProfile(Profile* profile); + + // Returns the Extension that implements the theme associated with + // |profile|. Returns NULL if the theme is no longer installed, if there is + // no installed theme, or the theme was cleared. + static const Extension* GetThemeForProfile(Profile* profile); + + // Forces an association between |profile| and |provider|. Used in unit tests + // where we need to mock BrowserThemeProvider. + static void ForceAssociationBetween(Profile* profile, + BrowserThemeProvider* provider); + + static ThemeServiceFactory* GetInstance(); + + private: + friend struct DefaultSingletonTraits<ThemeServiceFactory>; + + ThemeServiceFactory(); + ~ThemeServiceFactory(); + + // Maps |profile| to |provider| and listens for notifications relating to + // either. + void Associate(Profile* profile, BrowserThemeProvider* provider); + + // NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + NotificationRegistrar registrar_; + std::map<Profile*, BrowserThemeProvider*> mapping_; +}; + +#endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_ |