blob: 5038dff43fda6cc10bde33a201bdca4723832f23 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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#include "chrome/browser/themes/theme_service.h"
6
7#include "base/bind.h"
8#include "base/memory/ref_counted_memory.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "base/prefs/pref_service.h"
10#include "base/sequenced_task_runner.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010011#include "base/strings/string_util.h"
12#include "base/strings/utf_string_conversions.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010013#include "chrome/browser/chrome_notification_types.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000014#include "chrome/browser/extensions/extension_service.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000015#include "chrome/browser/extensions/extension_system.h"
Ben Murdoch2385ea32013-08-06 11:01:04 +010016#include "chrome/browser/managed_mode/managed_user_theme.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000017#include "chrome/browser/profiles/profile.h"
18#include "chrome/browser/themes/browser_theme_pack.h"
Ben Murdoch558790d2013-07-30 15:19:42 +010019#include "chrome/browser/themes/custom_theme_supplier.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000020#include "chrome/browser/themes/theme_properties.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000021#include "chrome/browser/themes/theme_syncable_service.h"
22#include "chrome/common/chrome_constants.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023#include "chrome/common/extensions/extension_manifest_constants.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024#include "chrome/common/pref_names.h"
25#include "content/public/browser/notification_service.h"
26#include "content/public/browser/user_metrics.h"
27#include "grit/theme_resources.h"
28#include "grit/ui_resources.h"
29#include "ui/base/layout.h"
30#include "ui/base/resource/resource_bundle.h"
31#include "ui/gfx/image/image_skia.h"
32
33#if defined(OS_WIN)
34#include "ui/base/win/shell.h"
35#endif
36
Torne (Richard Coles)58218062012-11-14 11:43:16 +000037using content::BrowserThread;
38using content::UserMetricsAction;
39using extensions::Extension;
40using ui::ResourceBundle;
41
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000042typedef ThemeProperties Properties;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000043
44// The default theme if we haven't installed a theme yet or if we've clicked
45// the "Use Classic" button.
46const char* ThemeService::kDefaultThemeID = "";
47
48namespace {
49
50// The default theme if we've gone to the theme gallery and installed the
51// "Default" theme. We have to detect this case specifically. (By the time we
52// realize we've installed the default theme, we already have an extension
53// unpacked on the filesystem.)
54const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
55
56SkColor TintForUnderline(SkColor input) {
57 return SkColorSetA(input, SkColorGetA(input) / 3);
58}
59
60SkColor IncreaseLightness(SkColor color, double percent) {
61 color_utils::HSL result;
62 color_utils::SkColorToHSL(color, &result);
63 result.l += (1 - result.l) * percent;
64 return color_utils::HSLToSkColor(result, SkColorGetA(color));
65}
66
Torne (Richard Coles)58218062012-11-14 11:43:16 +000067// Writes the theme pack to disk on a separate thread.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000068void WritePackToDiskCallback(BrowserThemePack* pack,
69 const base::FilePath& path) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070 if (!pack->WriteToDisk(path))
71 NOTREACHED() << "Could not write theme pack to disk";
72}
73
74} // namespace
75
Torne (Richard Coles)58218062012-11-14 11:43:16 +000076ThemeService::ThemeService()
Ben Murdochbb1529c2013-08-08 10:24:53 +010077 : ready_(false),
78 rb_(ResourceBundle::GetSharedInstance()),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000079 profile_(NULL),
Ben Murdochbb1529c2013-08-08 10:24:53 +010080 number_of_infobars_(0) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000081}
82
83ThemeService::~ThemeService() {
84 FreePlatformCaches();
85}
86
87void ThemeService::Init(Profile* profile) {
88 DCHECK(CalledOnValidThread());
89 profile_ = profile;
90
Torne (Richard Coles)58218062012-11-14 11:43:16 +000091 LoadThemePrefs();
92
Ben Murdochbb1529c2013-08-08 10:24:53 +010093 if (!ready_) {
94 registrar_.Add(this,
95 chrome::NOTIFICATION_EXTENSIONS_READY,
96 content::Source<Profile>(profile_));
97 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000098
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this));
100}
101
102gfx::Image ThemeService::GetImageNamed(int id) const {
103 DCHECK(CalledOnValidThread());
104
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100105 gfx::Image image;
Ben Murdoch558790d2013-07-30 15:19:42 +0100106 if (theme_supplier_.get())
107 image = theme_supplier_->GetImageNamed(id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000108
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100109 if (image.IsEmpty())
110 image = rb_.GetNativeImageNamed(id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100112 return image;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000113}
114
115gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const {
116 gfx::Image image = GetImageNamed(id);
117 if (image.IsEmpty())
118 return NULL;
119 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns
120 // its images const. GetImageSkiaNamed() also should but has many callsites.
121 return const_cast<gfx::ImageSkia*>(image.ToImageSkia());
122}
123
124SkColor ThemeService::GetColor(int id) const {
125 DCHECK(CalledOnValidThread());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000126 SkColor color;
Ben Murdoch558790d2013-07-30 15:19:42 +0100127 if (theme_supplier_.get() && theme_supplier_->GetColor(id, &color))
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000128 return color;
129
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000130 // For backward compat with older themes, some newer colors are generated from
131 // older ones if they are missing.
132 switch (id) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000133 case Properties::COLOR_NTP_SECTION_HEADER_TEXT:
134 return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.30);
135 case Properties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
136 return GetColor(Properties::COLOR_NTP_TEXT);
137 case Properties::COLOR_NTP_SECTION_HEADER_RULE:
138 return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.70);
139 case Properties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
140 return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.86);
141 case Properties::COLOR_NTP_TEXT_LIGHT:
142 return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.40);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100143 case Properties::COLOR_MANAGED_USER_LABEL:
Ben Murdoch558790d2013-07-30 15:19:42 +0100144 return color_utils::GetReadableColor(
145 SK_ColorWHITE,
146 GetColor(Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND));
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100147 case Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND:
Ben Murdoch558790d2013-07-30 15:19:42 +0100148 return color_utils::BlendTowardOppositeLuminance(
149 GetColor(Properties::COLOR_FRAME), 0x80);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000150 }
151
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000152 return Properties::GetDefaultColor(id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000153}
154
155bool ThemeService::GetDisplayProperty(int id, int* result) const {
Ben Murdoch558790d2013-07-30 15:19:42 +0100156 if (theme_supplier_.get())
157 return theme_supplier_->GetDisplayProperty(id, result);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000158
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000159 return Properties::GetDefaultDisplayProperty(id, result);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000160}
161
162bool ThemeService::ShouldUseNativeFrame() const {
163 if (HasCustomImage(IDR_THEME_FRAME))
164 return false;
165#if defined(OS_WIN)
166 return ui::win::IsAeroGlassEnabled();
167#else
168 return false;
169#endif
170}
171
172bool ThemeService::HasCustomImage(int id) const {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000173 if (!Properties::IsThemeableImage(id))
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000174 return false;
175
Ben Murdoch558790d2013-07-30 15:19:42 +0100176 if (theme_supplier_.get())
177 return theme_supplier_->HasCustomImage(id);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100178
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000179 return false;
180}
181
182base::RefCountedMemory* ThemeService::GetRawData(
183 int id,
184 ui::ScaleFactor scale_factor) const {
185 // Check to see whether we should substitute some images.
186 int ntp_alternate;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000187 GetDisplayProperty(Properties::NTP_LOGO_ALTERNATE, &ntp_alternate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000188 if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0)
189 id = IDR_PRODUCT_LOGO_WHITE;
190
191 base::RefCountedMemory* data = NULL;
Ben Murdoch558790d2013-07-30 15:19:42 +0100192 if (theme_supplier_.get())
193 data = theme_supplier_->GetRawData(id, scale_factor);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000194 if (!data)
195 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P);
196
197 return data;
198}
199
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000200void ThemeService::Observe(int type,
201 const content::NotificationSource& source,
202 const content::NotificationDetails& details) {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100203 DCHECK(type == chrome::NOTIFICATION_EXTENSIONS_READY);
204 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
205 content::Source<Profile>(profile_));
206
207 MigrateTheme();
208 set_ready();
209
210 // Send notification in case anyone requested data and cached it when the
211 // theme service was not ready yet.
212 NotifyThemeChanged();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000213}
214
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000215void ThemeService::SetTheme(const Extension* extension) {
216 // Clear our image cache.
217 FreePlatformCaches();
218
Ben Murdochbb1529c2013-08-08 10:24:53 +0100219 DCHECK(extension);
220 DCHECK(extension->is_theme());
221 if (DCHECK_IS_ON()) {
222 ExtensionService* service =
223 extensions::ExtensionSystem::Get(profile_)->extension_service();
224 DCHECK(service);
225 DCHECK(service->GetExtensionById(extension->id(), false));
226 }
227
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000228 BuildFromExtension(extension);
229 SaveThemeID(extension->id());
230
231 NotifyThemeChanged();
232 content::RecordAction(UserMetricsAction("Themes_Installed"));
233}
234
Ben Murdoch558790d2013-07-30 15:19:42 +0100235void ThemeService::SetCustomDefaultTheme(
236 scoped_refptr<CustomThemeSupplier> theme_supplier) {
237 ClearAllThemeData();
238 SwapThemeSupplier(theme_supplier);
239 NotifyThemeChanged();
240}
241
242bool ThemeService::ShouldInitWithNativeTheme() const {
243 return false;
244}
245
Ben Murdochbb1529c2013-08-08 10:24:53 +0100246void ThemeService::RemoveUnusedThemes() {
Ben Murdoch558790d2013-07-30 15:19:42 +0100247 // We do not want to garbage collect themes on startup (|ready_| is false).
Ben Murdochbb1529c2013-08-08 10:24:53 +0100248 // Themes will get garbage collected once
249 // ExtensionService::GarbageCollectExtensions() runs.
Ben Murdoch558790d2013-07-30 15:19:42 +0100250 if (!profile_ || !ready_)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000251 return;
Ben Murdoch558790d2013-07-30 15:19:42 +0100252
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000253 ExtensionService* service = profile_->GetExtensionService();
254 if (!service)
255 return;
256 std::string current_theme = GetThemeID();
257 std::vector<std::string> remove_list;
Ben Murdochbb1529c2013-08-08 10:24:53 +0100258 const ExtensionSet* extensions = service->extensions();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000259 for (ExtensionSet::const_iterator it = extensions->begin();
260 it != extensions->end(); ++it) {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100261 if ((*it)->is_theme() && (*it)->id() != current_theme) {
262 remove_list.push_back((*it)->id());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000263 }
264 }
265 for (size_t i = 0; i < remove_list.size(); ++i)
266 service->UninstallExtension(remove_list[i], false, NULL);
267}
268
269void ThemeService::UseDefaultTheme() {
Ben Murdoch558790d2013-07-30 15:19:42 +0100270 if (ready_)
271 content::RecordAction(UserMetricsAction("Themes_Reset"));
272 if (IsManagedUser()) {
273 SetManagedUserTheme();
274 return;
275 }
Ben Murdochbb1529c2013-08-08 10:24:53 +0100276 ClearAllThemeData();
277 NotifyThemeChanged();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000278}
279
280void ThemeService::SetNativeTheme() {
281 UseDefaultTheme();
282}
283
284bool ThemeService::UsingDefaultTheme() const {
285 std::string id = GetThemeID();
286 return id == ThemeService::kDefaultThemeID ||
Ben Murdoch558790d2013-07-30 15:19:42 +0100287 (id == kDefaultThemeGalleryID && !IsManagedUser());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000288}
289
290bool ThemeService::UsingNativeTheme() const {
291 return UsingDefaultTheme();
292}
293
294std::string ThemeService::GetThemeID() const {
295 return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
296}
297
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000298color_utils::HSL ThemeService::GetTint(int id) const {
299 DCHECK(CalledOnValidThread());
300
301 color_utils::HSL hsl;
Ben Murdoch558790d2013-07-30 15:19:42 +0100302 if (theme_supplier_.get() && theme_supplier_->GetTint(id, &hsl))
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000303 return hsl;
304
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000305 return ThemeProperties::GetDefaultTint(id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000306}
307
308void ThemeService::ClearAllThemeData() {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100309 if (!ready_)
310 return;
311
Ben Murdoch558790d2013-07-30 15:19:42 +0100312 SwapThemeSupplier(NULL);
313
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000314 // Clear our image cache.
315 FreePlatformCaches();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000316
317 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
318 SaveThemeID(kDefaultThemeID);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100319
Ben Murdochbb1529c2013-08-08 10:24:53 +0100320 RemoveUnusedThemes();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000321}
322
323void ThemeService::LoadThemePrefs() {
324 PrefService* prefs = profile_->GetPrefs();
325
326 std::string current_id = GetThemeID();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000327 if (current_id == kDefaultThemeID) {
Ben Murdoch558790d2013-07-30 15:19:42 +0100328 // Managed users have a different default theme.
329 if (IsManagedUser())
330 SetManagedUserTheme();
331 else if (ShouldInitWithNativeTheme())
332 SetNativeTheme();
333 else
334 UseDefaultTheme();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000335 set_ready();
336 return;
337 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000338
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000339 bool loaded_pack = false;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000340
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000341 // If we don't have a file pack, we're updating from an old version.
342 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename);
343 if (path != base::FilePath()) {
Ben Murdoch558790d2013-07-30 15:19:42 +0100344 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id));
345 loaded_pack = theme_supplier_.get() != NULL;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000346 }
347
348 if (loaded_pack) {
349 content::RecordAction(UserMetricsAction("Themes.Loaded"));
350 set_ready();
Ben Murdochbb1529c2013-08-08 10:24:53 +0100351 } else {
352 // TODO(erg): We need to pop up a dialog informing the user that their
353 // theme is being migrated.
354 ExtensionService* service =
355 extensions::ExtensionSystem::Get(profile_)->extension_service();
356 if (service && service->is_ready()) {
357 MigrateTheme();
358 set_ready();
359 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000360 }
361}
362
363void ThemeService::NotifyThemeChanged() {
Ben Murdoch558790d2013-07-30 15:19:42 +0100364 if (!ready_)
365 return;
366
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000367 DVLOG(1) << "Sending BROWSER_THEME_CHANGED";
368 // Redraw!
369 content::NotificationService* service =
370 content::NotificationService::current();
371 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
372 content::Source<ThemeService>(this),
373 content::NotificationService::NoDetails());
374#if defined(OS_MACOSX)
375 NotifyPlatformThemeChanged();
376#endif // OS_MACOSX
377
378 // Notify sync that theme has changed.
379 if (theme_syncable_service_.get()) {
380 theme_syncable_service_->OnThemeChange();
381 }
382}
383
384#if defined(OS_WIN) || defined(USE_AURA)
385void ThemeService::FreePlatformCaches() {
386 // Views (Skia) has no platform image cache to clear.
387}
388#endif
389
Ben Murdochbb1529c2013-08-08 10:24:53 +0100390void ThemeService::SwapThemeSupplier(
391 scoped_refptr<CustomThemeSupplier> theme_supplier) {
392 if (theme_supplier_.get())
393 theme_supplier_->StopUsingTheme();
394 theme_supplier_ = theme_supplier;
395 if (theme_supplier_.get())
396 theme_supplier_->StartUsingTheme();
Ben Murdoch558790d2013-07-30 15:19:42 +0100397}
398
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000399void ThemeService::MigrateTheme() {
400 ExtensionService* service =
401 extensions::ExtensionSystem::Get(profile_)->extension_service();
402 const Extension* extension = service ?
403 service->GetExtensionById(GetThemeID(), false) : NULL;
404 if (extension) {
405 DLOG(ERROR) << "Migrating theme";
406 BuildFromExtension(extension);
407 content::RecordAction(UserMetricsAction("Themes.Migrated"));
408 } else {
409 DLOG(ERROR) << "Theme is mysteriously gone.";
410 ClearAllThemeData();
411 content::RecordAction(UserMetricsAction("Themes.Gone"));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000412 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000413}
414
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000415void ThemeService::SavePackName(const base::FilePath& pack_path) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000416 profile_->GetPrefs()->SetFilePath(
417 prefs::kCurrentThemePackFilename, pack_path);
418}
419
420void ThemeService::SaveThemeID(const std::string& id) {
421 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id);
422}
423
424void ThemeService::BuildFromExtension(const Extension* extension) {
425 scoped_refptr<BrowserThemePack> pack(
426 BrowserThemePack::BuildFromExtension(extension));
427 if (!pack.get()) {
428 // TODO(erg): We've failed to install the theme; perhaps we should tell the
429 // user? http://crbug.com/34780
430 LOG(ERROR) << "Could not load theme.";
431 return;
432 }
433
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000434 ExtensionService* service =
435 extensions::ExtensionSystem::Get(profile_)->extension_service();
436 if (!service)
437 return;
438
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000439 // Write the packed file to disk.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000440 base::FilePath pack_path =
441 extension->path().Append(chrome::kThemePackFilename);
442 service->GetFileTaskRunner()->PostTask(
443 FROM_HERE,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000444 base::Bind(&WritePackToDiskCallback, pack, pack_path));
445
446 SavePackName(pack_path);
Ben Murdoch558790d2013-07-30 15:19:42 +0100447 SwapThemeSupplier(pack);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000448}
449
Ben Murdocheb525c52013-07-10 11:40:50 +0100450bool ThemeService::IsManagedUser() const {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100451 return profile_->IsManaged();
Ben Murdocheb525c52013-07-10 11:40:50 +0100452}
453
Ben Murdoch558790d2013-07-30 15:19:42 +0100454void ThemeService::SetManagedUserTheme() {
Ben Murdoch558790d2013-07-30 15:19:42 +0100455 SetCustomDefaultTheme(new ManagedUserTheme);
Ben Murdoch558790d2013-07-30 15:19:42 +0100456}
457
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000458void ThemeService::OnInfobarDisplayed() {
459 number_of_infobars_++;
460}
461
462void ThemeService::OnInfobarDestroyed() {
463 number_of_infobars_--;
464
465 if (number_of_infobars_ == 0)
Ben Murdochbb1529c2013-08-08 10:24:53 +0100466 RemoveUnusedThemes();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000467}
468
469ThemeSyncableService* ThemeService::GetThemeSyncableService() const {
470 return theme_syncable_service_.get();
471}