theme_service.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/managed_mode/managed_user_service.h"
17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/managed_mode/managed_user_service_factory.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/managed_mode/managed_user_theme.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/browser_theme_pack.h"
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/themes/custom_theme_supplier.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_syncable_service.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::ResourceBundle;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef ThemeProperties Properties;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default theme if we haven't installed a theme yet or if we've clicked
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the "Use Classic" button.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ThemeService::kDefaultThemeID = "";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default theme if we've gone to the theme gallery and installed the
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Default" theme. We have to detect this case specifically. (By the time we
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// realize we've installed the default theme, we already have an extension
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unpacked on the filesystem.)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor TintForUnderline(SkColor input) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SkColorSetA(input, SkColorGetA(input) / 3);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor IncreaseLightness(SkColor color, double percent) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL result;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::SkColorToHSL(color, &result);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.l += (1 - result.l) * percent;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return color_utils::HSLToSkColor(result, SkColorGetA(color));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes the theme pack to disk on a separate thread.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WritePackToDiskCallback(BrowserThemePack* pack,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const base::FilePath& path) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pack->WriteToDisk(path))
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Could not write theme pack to disk";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeService::ThemeService()
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    : ready_(false),
80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      rb_(ResourceBundle::GetSharedInstance()),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(NULL),
82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      number_of_infobars_(0),
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      weak_ptr_factory_(this) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeService::~ThemeService() {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreePlatformCaches();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::Init(Profile* profile) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_ = profile;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ManagedUserServiceFactory::GetForProfile(profile)->AddInitCallback(base::Bind(
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      &ThemeService::OnManagedUserInitialized, weak_ptr_factory_.GetWeakPtr()));
96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadThemePrefs();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!ready_) {
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    registrar_.Add(this,
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                   chrome::NOTIFICATION_EXTENSIONS_READY,
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                   content::Source<Profile>(profile_));
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  theme_syncable_service_.reset(new ThemeSyncableService(profile_, this));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image ThemeService::GetImageNamed(int id) const {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Image image;
112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get())
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    image = theme_supplier_->GetImageNamed(id);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (image.IsEmpty())
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    image = rb_.GetNativeImageNamed(id);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return image;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image image = GetImageNamed(id);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image.IsEmpty())
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pkotwicz): Remove this const cast.  The gfx::Image interface returns
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its images const. GetImageSkiaNamed() also should but has many callsites.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return const_cast<gfx::ImageSkia*>(image.ToImageSkia());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor ThemeService::GetColor(int id) const {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color;
133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get() && theme_supplier_->GetColor(id, &color))
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return color;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For backward compat with older themes, some newer colors are generated from
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // older ones if they are missing.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (id) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Properties::COLOR_NTP_SECTION_HEADER_TEXT:
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.30);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Properties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetColor(Properties::COLOR_NTP_TEXT);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Properties::COLOR_NTP_SECTION_HEADER_RULE:
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.70);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Properties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.86);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Properties::COLOR_NTP_TEXT_LIGHT:
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.40);
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case Properties::COLOR_MANAGED_USER_LABEL:
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return color_utils::GetReadableColor(
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          SK_ColorWHITE,
152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          GetColor(Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND));
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND:
154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return color_utils::BlendTowardOppositeLuminance(
155558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          GetColor(Properties::COLOR_FRAME), 0x80);
156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case Properties::COLOR_MANAGED_USER_LABEL_BORDER:
157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return color_utils::AlphaBlend(
158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          GetColor(Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND),
159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          SK_ColorBLACK,
160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          230);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Properties::GetDefaultColor(id);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::GetDisplayProperty(int id, int* result) const {
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get())
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return theme_supplier_->GetDisplayProperty(id, result);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Properties::GetDefaultDisplayProperty(id, result);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::ShouldUseNativeFrame() const {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasCustomImage(IDR_THEME_FRAME))
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::win::IsAeroGlassEnabled();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::HasCustomImage(int id) const {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Properties::IsThemeableImage(id))
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get())
188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return theme_supplier_->HasCustomImage(id);
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::RefCountedMemory* ThemeService::GetRawData(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScaleFactor scale_factor) const {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see whether we should substitute some images.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ntp_alternate;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetDisplayProperty(Properties::NTP_LOGO_ALTERNATE, &ntp_alternate);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDR_PRODUCT_LOGO_WHITE;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::RefCountedMemory* data = NULL;
203558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get())
204558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    data = theme_supplier_->GetRawData(id, scale_factor);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!data)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::Observe(int type,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const content::NotificationSource& source,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const content::NotificationDetails& details) {
214bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DCHECK(type == chrome::NOTIFICATION_EXTENSIONS_READY);
215bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
216bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      content::Source<Profile>(profile_));
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  MigrateTheme();
219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  set_ready();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Send notification in case anyone requested data and cached it when the
222bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // theme service was not ready yet.
223bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  NotifyThemeChanged();
224bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
226bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ThemeService::SetTheme(const Extension* extension) {
227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Clear our image cache.
228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FreePlatformCaches();
229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
230bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DCHECK(extension);
231bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DCHECK(extension->is_theme());
232bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (DCHECK_IS_ON()) {
233bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    ExtensionService* service =
234bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        extensions::ExtensionSystem::Get(profile_)->extension_service();
235bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DCHECK(service);
236bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DCHECK(service->GetExtensionById(extension->id(), false));
237bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
238bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFromExtension(extension);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SaveThemeID(extension->id());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyThemeChanged();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Themes_Installed"));
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThemeService::SetCustomDefaultTheme(
247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    scoped_refptr<CustomThemeSupplier> theme_supplier) {
248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ClearAllThemeData();
249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SwapThemeSupplier(theme_supplier);
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  NotifyThemeChanged();
251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool ThemeService::ShouldInitWithNativeTheme() const {
254558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return false;
255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
257bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ThemeService::RemoveUnusedThemes() {
258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // We do not want to garbage collect themes on startup (|ready_| is false).
259bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Themes will get garbage collected once
260bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // ExtensionService::GarbageCollectExtensions() runs.
261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!profile_ || !ready_)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service = profile_->GetExtensionService();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!service)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string current_theme = GetThemeID();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> remove_list;
269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const ExtensionSet* extensions = service->extensions();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator it = extensions->begin();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != extensions->end(); ++it) {
272bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    if ((*it)->is_theme() && (*it)->id() != current_theme) {
273bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      remove_list.push_back((*it)->id());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < remove_list.size(); ++i)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service->UninstallExtension(remove_list[i], false, NULL);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::UseDefaultTheme() {
281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (ready_)
282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    content::RecordAction(UserMetricsAction("Themes_Reset"));
283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (IsManagedUser()) {
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetManagedUserTheme();
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
287bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ClearAllThemeData();
288bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  NotifyThemeChanged();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::SetNativeTheme() {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseDefaultTheme();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::UsingDefaultTheme() const {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id = GetThemeID();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id == ThemeService::kDefaultThemeID ||
298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      (id == kDefaultThemeGalleryID && !IsManagedUser());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::UsingNativeTheme() const {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UsingDefaultTheme();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ThemeService::GetThemeID() const {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)color_utils::HSL ThemeService::GetTint(int id) const {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL hsl;
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (theme_supplier_.get() && theme_supplier_->GetTint(id, &hsl))
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hsl;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ThemeProperties::GetDefaultTint(id);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::ClearAllThemeData() {
320bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!ready_)
321bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return;
322bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SwapThemeSupplier(NULL);
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear our image cache.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreePlatformCaches();
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SaveThemeID(kDefaultThemeID);
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
331bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  RemoveUnusedThemes();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::LoadThemePrefs() {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string current_id = GetThemeID();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_id == kDefaultThemeID) {
339558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Managed users have a different default theme.
340558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (IsManagedUser())
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetManagedUserTheme();
342558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    else if (ShouldInitWithNativeTheme())
343558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetNativeTheme();
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    else
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      UseDefaultTheme();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    set_ready();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool loaded_pack = false;
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we don't have a file pack, we're updating from an old version.
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (path != base::FilePath()) {
355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id));
356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    loaded_pack = theme_supplier_.get() != NULL;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (loaded_pack) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RecordAction(UserMetricsAction("Themes.Loaded"));
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    set_ready();
362bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  } else {
363bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    // TODO(erg): We need to pop up a dialog informing the user that their
364bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    // theme is being migrated.
365bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    ExtensionService* service =
366bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        extensions::ExtensionSystem::Get(profile_)->extension_service();
367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    if (service && service->is_ready()) {
368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      MigrateTheme();
369bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      set_ready();
370bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::NotifyThemeChanged() {
375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!ready_)
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Sending BROWSER_THEME_CHANGED";
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redraw!
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService* service =
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  content::Source<ThemeService>(this),
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  content::NotificationService::NoDetails());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyPlatformThemeChanged();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_MACOSX
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify sync that theme has changed.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (theme_syncable_service_.get()) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    theme_syncable_service_->OnThemeChange();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(USE_AURA)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::FreePlatformCaches() {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Views (Skia) has no platform image cache to clear.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
401bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ThemeService::SwapThemeSupplier(
402bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<CustomThemeSupplier> theme_supplier) {
403bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (theme_supplier_.get())
404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    theme_supplier_->StopUsingTheme();
405bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  theme_supplier_ = theme_supplier;
406bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (theme_supplier_.get())
407bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    theme_supplier_->StartUsingTheme();
408558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
409558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::MigrateTheme() {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service =
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service();
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* extension = service ?
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service->GetExtensionById(GetThemeID(), false) : NULL;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension) {
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Migrating theme";
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BuildFromExtension(extension);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RecordAction(UserMetricsAction("Themes.Migrated"));
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Theme is mysteriously gone.";
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClearAllThemeData();
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RecordAction(UserMetricsAction("Themes.Gone"));
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::SavePackName(const base::FilePath& pack_path) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetFilePath(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kCurrentThemePackFilename, pack_path);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::SaveThemeID(const std::string& id) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::BuildFromExtension(const Extension* extension) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserThemePack> pack(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThemePack::BuildFromExtension(extension));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pack.get()) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(erg): We've failed to install the theme; perhaps we should tell the
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // user? http://crbug.com/34780
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not load theme.";
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service =
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service();
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!service)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write the packed file to disk.
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pack_path =
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension->path().Append(chrome::kThemePackFilename);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service->GetFileTaskRunner()->PostTask(
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&WritePackToDiskCallback, pack, pack_path));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SavePackName(pack_path);
458558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SwapThemeSupplier(pack);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ThemeService::IsManagedUser() const {
462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return profile_->IsManaged();
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
465558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThemeService::SetManagedUserTheme() {
466558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SetCustomDefaultTheme(new ManagedUserTheme);
467558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
468558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
469ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ThemeService::OnManagedUserInitialized() {
470ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Currently when creating a supervised user, the ThemeService is initialized
471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // before the boolean flag indicating the profile belongs to a supervised
472ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // user gets set. In order to get the custom managed user theme, we get a
473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // callback when ManagedUserService is initialized, which happens some time
474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // after the boolean flag has been set in
475ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // ProfileManager::InitProfileUserPrefs() and after the
476ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // NOTIFICATION_EXTENSIONS_READY notification is sent.
477ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (theme_supplier_.get() || !IsManagedUser())
478ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return;
479ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
480ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetManagedUserTheme();
481ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
482ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::OnInfobarDisplayed() {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  number_of_infobars_++;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::OnInfobarDestroyed() {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  number_of_infobars_--;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (number_of_infobars_ == 0)
491bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    RemoveUnusedThemes();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeSyncableService* ThemeService::GetThemeSyncableService() const {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return theme_syncable_service_.get();
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
497