Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: chrome/browser/themes/theme_service.cc

Issue 19462009: [DRAFT] Allow a user to revert to their previous theme without closing infobar (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/themes/theme_service.h ('k') | chrome/browser/themes/theme_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/themes/theme_service.h" 5 #include "chrome/browser/themes/theme_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ref_counted_memory.h" 8 #include "base/memory/ref_counted_memory.h"
9 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
10 #include "base/sequenced_task_runner.h" 11 #include "base/sequenced_task_runner.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extension_system.h" 16 #include "chrome/browser/extensions/extension_system.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/themes/browser_theme_pack.h" 18 #include "chrome/browser/themes/browser_theme_pack.h"
18 #include "chrome/browser/themes/custom_theme_supplier.h" 19 #include "chrome/browser/themes/custom_theme_supplier.h"
(...skipping 30 matching lines...) Expand all
49 const char* ThemeService::kDefaultThemeID = ""; 50 const char* ThemeService::kDefaultThemeID = "";
50 51
51 namespace { 52 namespace {
52 53
53 // The default theme if we've gone to the theme gallery and installed the 54 // The default theme if we've gone to the theme gallery and installed the
54 // "Default" theme. We have to detect this case specifically. (By the time we 55 // "Default" theme. We have to detect this case specifically. (By the time we
55 // realize we've installed the default theme, we already have an extension 56 // realize we've installed the default theme, we already have an extension
56 // unpacked on the filesystem.) 57 // unpacked on the filesystem.)
57 const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn"; 58 const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
58 59
60 // Wait this many seconds after startup to garbage collect unused themes.
61 // Removing unused themes is done after a delay because there is no
62 // reason to do it at startup.
63 // ExtensionService::GarbageCollectExtensions() does something similar.
64 const int kRemoveUnusedThemesStartupDelay = 30;
65
59 SkColor TintForUnderline(SkColor input) { 66 SkColor TintForUnderline(SkColor input) {
60 return SkColorSetA(input, SkColorGetA(input) / 3); 67 return SkColorSetA(input, SkColorGetA(input) / 3);
61 } 68 }
62 69
63 SkColor IncreaseLightness(SkColor color, double percent) { 70 SkColor IncreaseLightness(SkColor color, double percent) {
64 color_utils::HSL result; 71 color_utils::HSL result;
65 color_utils::SkColorToHSL(color, &result); 72 color_utils::SkColorToHSL(color, &result);
66 result.l += (1 - result.l) * percent; 73 result.l += (1 - result.l) * percent;
67 return color_utils::HSLToSkColor(result, SkColorGetA(color)); 74 return color_utils::HSLToSkColor(result, SkColorGetA(color));
68 } 75 }
69 76
70 // Writes the theme pack to disk on a separate thread. 77 // Writes the theme pack to disk on a separate thread.
71 void WritePackToDiskCallback(BrowserThemePack* pack, 78 void WritePackToDiskCallback(BrowserThemePack* pack,
72 const base::FilePath& path) { 79 const base::FilePath& path) {
73 if (!pack->WriteToDisk(path)) 80 if (!pack->WriteToDisk(path))
74 NOTREACHED() << "Could not write theme pack to disk"; 81 NOTREACHED() << "Could not write theme pack to disk";
75 } 82 }
76 83
77 } // namespace 84 } // namespace
78 85
79 ThemeService::ThemeService() 86 ThemeService::ThemeService()
80 : rb_(ResourceBundle::GetSharedInstance()), 87 : rb_(ResourceBundle::GetSharedInstance()),
81 profile_(NULL), 88 profile_(NULL),
82 ready_(false), 89 ready_(false),
83 number_of_infobars_(0) { 90 installed_pending_load_id_(kDefaultThemeID),
91 number_of_infobars_(0),
92 weak_ptr_factory_(this) {
84 } 93 }
85 94
86 ThemeService::~ThemeService() { 95 ThemeService::~ThemeService() {
87 FreePlatformCaches(); 96 FreePlatformCaches();
88 } 97 }
89 98
90 void ThemeService::Init(Profile* profile) { 99 void ThemeService::Init(Profile* profile) {
91 DCHECK(CalledOnValidThread()); 100 DCHECK(CalledOnValidThread());
92 profile_ = profile; 101 profile_ = profile;
93 102
94 LoadThemePrefs(); 103 LoadThemePrefs();
95 104
96 if (!ready_) { 105 registrar_.Add(this,
97 registrar_.Add(this, 106 chrome::NOTIFICATION_EXTENSIONS_READY,
98 chrome::NOTIFICATION_EXTENSIONS_READY, 107 content::Source<Profile>(profile_));
99 content::Source<Profile>(profile_));
100 }
101 108
102 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); 109 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this));
103 } 110 }
104 111
105 gfx::Image ThemeService::GetImageNamed(int id) const { 112 gfx::Image ThemeService::GetImageNamed(int id) const {
106 DCHECK(CalledOnValidThread()); 113 DCHECK(CalledOnValidThread());
107 114
108 gfx::Image image; 115 gfx::Image image;
109 if (theme_supplier_.get()) 116 if (theme_supplier_.get())
110 image = theme_supplier_->GetImageNamed(id); 117 image = theme_supplier_->GetImageNamed(id);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 data = theme_supplier_->GetRawData(id, scale_factor); 203 data = theme_supplier_->GetRawData(id, scale_factor);
197 if (!data) 204 if (!data)
198 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); 205 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P);
199 206
200 return data; 207 return data;
201 } 208 }
202 209
203 void ThemeService::Observe(int type, 210 void ThemeService::Observe(int type,
204 const content::NotificationSource& source, 211 const content::NotificationSource& source,
205 const content::NotificationDetails& details) { 212 const content::NotificationDetails& details) {
206 DCHECK(type == chrome::NOTIFICATION_EXTENSIONS_READY); 213 using content::Details;
207 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, 214 switch (type) {
208 content::Source<Profile>(profile_)); 215 case chrome::NOTIFICATION_EXTENSIONS_READY:
209 216 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
210 MigrateTheme(); 217 content::Source<Profile>(profile_));
211 set_ready(); 218 OnExtensionServiceReady();
212 219 break;
213 // Send notification in case anyone requested data and cached it when the 220 case chrome::NOTIFICATION_EXTENSION_INSTALLED:
214 // theme service was not ready yet. 221 {
215 NotifyThemeChanged(); 222 // The theme may be initially disabled. Wait till it is loaded (if ever).
223 Details<const extensions::InstalledExtensionInfo> installed_details(
224 details);
225 if (installed_details->extension->is_theme())
226 installed_pending_load_id_ = installed_details->extension->id();
227 break;
228 }
229 case chrome::NOTIFICATION_EXTENSION_LOADED:
230 {
231 const Extension* extension = Details<const Extension>(details).ptr();
232 if (extension->is_theme() &&
233 installed_pending_load_id_ != kDefaultThemeID &&
234 installed_pending_load_id_ == extension->id()) {
235 SetTheme(extension);
236 }
237 installed_pending_load_id_ = kDefaultThemeID;
238 break;
239 }
240 case chrome::NOTIFICATION_EXTENSION_ENABLED:
241 {
242 const Extension* extension = Details<const Extension>(details).ptr();
243 if (extension->is_theme())
244 SetTheme(extension);
245 break;
246 }
247 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
248 {
249 Details<const extensions::UnloadedExtensionInfo> unloaded_details(
250 details);
251 if (unloaded_details->reason != extension_misc::UNLOAD_REASON_UPDATE &&
252 unloaded_details->extension->is_theme() &&
253 unloaded_details->extension->id() == GetThemeID()) {
254 UseDefaultTheme();
255 }
256 break;
257 }
258 }
216 } 259 }
217 260
218 void ThemeService::SetTheme(const Extension* extension) { 261 void ThemeService::SetTheme(const Extension* extension) {
262 DCHECK(extension->is_theme());
263 ExtensionService* service =
264 extensions::ExtensionSystem::Get(profile_)->extension_service();
265 if (!service->IsExtensionEnabled(extension->id())) {
266 // |extension| is disabled when reverting to the previous theme via an
267 // infobar.
268 service->EnableExtension(extension->id());
269 // Enabling the extension will call back to SetTheme().
270 return;
271 }
272
273 std::string previous_theme_id = GetThemeID();
274
219 // Clear our image cache. 275 // Clear our image cache.
220 FreePlatformCaches(); 276 FreePlatformCaches();
221 277
222 DCHECK(extension);
223 DCHECK(extension->is_theme());
224 if (DCHECK_IS_ON()) {
225 ExtensionService* service =
226 extensions::ExtensionSystem::Get(profile_)->extension_service();
227 DCHECK(service);
228 DCHECK(service->GetExtensionById(extension->id(), false));
229 }
230
231 BuildFromExtension(extension); 278 BuildFromExtension(extension);
232 SaveThemeID(extension->id()); 279 SaveThemeID(extension->id());
233 280
234 NotifyThemeChanged(); 281 NotifyThemeChanged();
235 content::RecordAction(UserMetricsAction("Themes_Installed")); 282 content::RecordAction(UserMetricsAction("Themes_Installed"));
283
284 if (previous_theme_id != kDefaultThemeID &&
285 previous_theme_id != extension->id()) {
286 // Disable the old theme.
287 service->DisableExtension(previous_theme_id,
288 extensions::Extension::DISABLE_USER_ACTION);
289 }
236 } 290 }
237 291
238 void ThemeService::SetCustomDefaultTheme( 292 void ThemeService::SetCustomDefaultTheme(
239 scoped_refptr<CustomThemeSupplier> theme_supplier) { 293 scoped_refptr<CustomThemeSupplier> theme_supplier) {
240 ClearAllThemeData(); 294 ClearAllThemeData();
241 SwapThemeSupplier(theme_supplier); 295 SwapThemeSupplier(theme_supplier);
242 NotifyThemeChanged(); 296 NotifyThemeChanged();
243 } 297 }
244 298
245 bool ThemeService::ShouldInitWithNativeTheme() const { 299 bool ThemeService::ShouldInitWithNativeTheme() const {
246 return false; 300 return false;
247 } 301 }
248 302
249 void ThemeService::RemoveUnusedThemes() { 303 void ThemeService::RemoveUnusedThemes(bool ignore_infobars) {
250 // We do not want to garbage collect themes on startup (|ready_| is false). 304 // We do not want to garbage collect themes on startup (|ready_| is false).
251 // Themes will get garbage collected once 305 // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|.
252 // ExtensionService::GarbageCollectExtensions() runs.
253 if (!profile_ || !ready_) 306 if (!profile_ || !ready_)
254 return; 307 return;
308 if (!ignore_infobars && number_of_infobars_ != 0)
309 return;
255 310
256 ExtensionService* service = profile_->GetExtensionService(); 311 ExtensionService* service = profile_->GetExtensionService();
257 if (!service) 312 if (!service)
258 return; 313 return;
259 std::string current_theme = GetThemeID(); 314 std::string current_theme = GetThemeID();
260 std::vector<std::string> remove_list; 315 std::vector<std::string> remove_list;
261 const ExtensionSet* extensions = service->extensions(); 316 scoped_ptr<const ExtensionSet> extensions(
317 service->GenerateInstalledExtensionsSet());
318 extensions::ExtensionPrefs* prefs = service->extension_prefs();
262 for (ExtensionSet::const_iterator it = extensions->begin(); 319 for (ExtensionSet::const_iterator it = extensions->begin();
263 it != extensions->end(); ++it) { 320 it != extensions->end(); ++it) {
264 if ((*it)->is_theme() && (*it)->id() != current_theme) { 321 const extensions::Extension* extension = *it;
265 remove_list.push_back((*it)->id()); 322 if (extension->is_theme() &&
323 extension->id() != current_theme) {
324 // Only uninstall themes which are not disabled or are disabled with
325 // reason DISABLE_USER_ACTION. We cannot blanket uninstall all disabled
326 // themes because externally installed themes are initially disabled.
327 int disable_reason = prefs->GetDisableReasons(extension->id());
328 if (!prefs->IsExtensionDisabled(extension->id()) ||
329 disable_reason == Extension::DISABLE_USER_ACTION) {
330 remove_list.push_back((*it)->id());
331 }
266 } 332 }
267 } 333 }
334 // TODO: Garbage collect all unused themes. This method misses themes which
335 // are installed but not loaded because they are blacklisted by a management
336 // policy provider.
337
268 for (size_t i = 0; i < remove_list.size(); ++i) 338 for (size_t i = 0; i < remove_list.size(); ++i)
269 service->UninstallExtension(remove_list[i], false, NULL); 339 service->UninstallExtension(remove_list[i], false, NULL);
270 } 340 }
271 341
272 void ThemeService::UseDefaultTheme() { 342 void ThemeService::UseDefaultTheme() {
273 if (ready_) 343 if (ready_)
274 content::RecordAction(UserMetricsAction("Themes_Reset")); 344 content::RecordAction(UserMetricsAction("Themes_Reset"));
275 if (IsManagedUser()) { 345 if (IsManagedUser()) {
276 SetManagedUserTheme(); 346 SetManagedUserTheme();
277 return; 347 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 382
313 void ThemeService::ClearAllThemeData() { 383 void ThemeService::ClearAllThemeData() {
314 SwapThemeSupplier(NULL); 384 SwapThemeSupplier(NULL);
315 385
316 // Clear our image cache. 386 // Clear our image cache.
317 FreePlatformCaches(); 387 FreePlatformCaches();
318 388
319 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); 389 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
320 SaveThemeID(kDefaultThemeID); 390 SaveThemeID(kDefaultThemeID);
321 391
322 RemoveUnusedThemes(); 392 // There should be no more infobars. This may not be the case because of
393 // http://crbug.com/62154
394 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may
395 // be called as a result of NOTIFICATION_EXTENSION_UNLOADED.
396 base::MessageLoop::current()->PostTask(FROM_HERE,
Jeffrey Yasskin 2013/08/06 21:46:01 In local test runs, I'm getting stack traces like:
397 base::Bind(&ThemeService::RemoveUnusedThemes,
398 weak_ptr_factory_.GetWeakPtr(),
399 true));
323 } 400 }
324 401
325 void ThemeService::LoadThemePrefs() { 402 void ThemeService::LoadThemePrefs() {
326 PrefService* prefs = profile_->GetPrefs(); 403 PrefService* prefs = profile_->GetPrefs();
327 404
328 std::string current_id = GetThemeID(); 405 std::string current_id = GetThemeID();
329 if (current_id == kDefaultThemeID) { 406 if (current_id == kDefaultThemeID) {
330 // Managed users have a different default theme. 407 // Managed users have a different default theme.
331 if (IsManagedUser()) 408 if (IsManagedUser())
332 SetManagedUserTheme(); 409 SetManagedUserTheme();
(...skipping 10 matching lines...) Expand all
343 // If we don't have a file pack, we're updating from an old version. 420 // If we don't have a file pack, we're updating from an old version.
344 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); 421 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename);
345 if (path != base::FilePath()) { 422 if (path != base::FilePath()) {
346 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); 423 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id));
347 loaded_pack = theme_supplier_.get() != NULL; 424 loaded_pack = theme_supplier_.get() != NULL;
348 } 425 }
349 426
350 if (loaded_pack) { 427 if (loaded_pack) {
351 content::RecordAction(UserMetricsAction("Themes.Loaded")); 428 content::RecordAction(UserMetricsAction("Themes.Loaded"));
352 set_ready(); 429 set_ready();
353 } else {
354 // TODO(erg): We need to pop up a dialog informing the user that their
355 // theme is being migrated.
356 ExtensionService* service =
357 extensions::ExtensionSystem::Get(profile_)->extension_service();
358 if (service && service->is_ready()) {
359 MigrateTheme();
360 set_ready();
361 }
362 } 430 }
431 // Else: wait for the extension service to be ready so that the theme pack
432 // can be recreated from the extension.
363 } 433 }
364 434
365 void ThemeService::NotifyThemeChanged() { 435 void ThemeService::NotifyThemeChanged() {
366 if (!ready_) 436 if (!ready_)
367 return; 437 return;
368 438
369 DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; 439 DVLOG(1) << "Sending BROWSER_THEME_CHANGED";
370 // Redraw! 440 // Redraw!
371 content::NotificationService* service = 441 content::NotificationService* service =
372 content::NotificationService::current(); 442 content::NotificationService::current();
373 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 443 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
374 content::Source<ThemeService>(this), 444 content::Source<ThemeService>(this),
375 content::NotificationService::NoDetails()); 445 content::NotificationService::NoDetails());
376 #if defined(OS_MACOSX) 446 #if defined(OS_MACOSX)
377 NotifyPlatformThemeChanged(); 447 NotifyPlatformThemeChanged();
378 #endif // OS_MACOSX 448 #endif // OS_MACOSX
379 449
380 // Notify sync that theme has changed. 450 // Notify sync that theme has changed.
381 if (theme_syncable_service_.get()) { 451 if (theme_syncable_service_.get()) {
382 theme_syncable_service_->OnThemeChange(); 452 theme_syncable_service_->OnThemeChange();
383 } 453 }
384 } 454 }
385 455
386 #if defined(OS_WIN) || defined(USE_AURA) 456 #if defined(OS_WIN) || defined(USE_AURA)
387 void ThemeService::FreePlatformCaches() { 457 void ThemeService::FreePlatformCaches() {
388 // Views (Skia) has no platform image cache to clear. 458 // Views (Skia) has no platform image cache to clear.
389 } 459 }
390 #endif 460 #endif
391 461
392 void ThemeService::SwapThemeSupplier( 462 void ThemeService::OnExtensionServiceReady() {
393 scoped_refptr<CustomThemeSupplier> theme_supplier) { 463 if (!ready_) {
394 if (theme_supplier_.get()) 464 // If the ThemeService is not ready yet, the custom theme data pack needs to
395 theme_supplier_->StopUsingTheme(); 465 // be recreated from the extension.
396 theme_supplier_ = theme_supplier; 466 MigrateTheme();
397 if (theme_supplier_.get()) 467 set_ready();
398 theme_supplier_->StartUsingTheme(); 468
469 // Send notification in case anyone requested data and cached it when the
470 // theme service was not ready yet.
471 NotifyThemeChanged();
472 }
473
474 registrar_.Add(this,
475 chrome::NOTIFICATION_EXTENSION_INSTALLED,
476 content::Source<Profile>(profile_));
477 registrar_.Add(this,
478 chrome::NOTIFICATION_EXTENSION_LOADED,
479 content::Source<Profile>(profile_));
480 registrar_.Add(this,
481 chrome::NOTIFICATION_EXTENSION_ENABLED,
482 content::Source<Profile>(profile_));
483 registrar_.Add(this,
484 chrome::NOTIFICATION_EXTENSION_UNLOADED,
485 content::Source<Profile>(profile_));
486
487 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
488 base::Bind(&ThemeService::RemoveUnusedThemes,
489 weak_ptr_factory_.GetWeakPtr(),
490 false),
491 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay));
399 } 492 }
400 493
401 void ThemeService::MigrateTheme() { 494 void ThemeService::MigrateTheme() {
495 // TODO(erg): We need to pop up a dialog informing the user that their
496 // theme is being migrated.
402 ExtensionService* service = 497 ExtensionService* service =
403 extensions::ExtensionSystem::Get(profile_)->extension_service(); 498 extensions::ExtensionSystem::Get(profile_)->extension_service();
404 const Extension* extension = service ? 499 const Extension* extension = service ?
405 service->GetExtensionById(GetThemeID(), false) : NULL; 500 service->GetExtensionById(GetThemeID(), false) : NULL;
406 if (extension) { 501 if (extension) {
407 DLOG(ERROR) << "Migrating theme"; 502 DLOG(ERROR) << "Migrating theme";
408 BuildFromExtension(extension); 503 BuildFromExtension(extension);
409 content::RecordAction(UserMetricsAction("Themes.Migrated")); 504 content::RecordAction(UserMetricsAction("Themes.Migrated"));
410 } else { 505 } else {
411 DLOG(ERROR) << "Theme is mysteriously gone."; 506 DLOG(ERROR) << "Theme is mysteriously gone.";
412 ClearAllThemeData(); 507 ClearAllThemeData();
413 content::RecordAction(UserMetricsAction("Themes.Gone")); 508 content::RecordAction(UserMetricsAction("Themes.Gone"));
414 } 509 }
415 } 510 }
416 511
512 void ThemeService::SwapThemeSupplier(
513 scoped_refptr<CustomThemeSupplier> theme_supplier) {
514 if (theme_supplier_.get())
515 theme_supplier_->StopUsingTheme();
516 theme_supplier_ = theme_supplier;
517 if (theme_supplier_.get())
518 theme_supplier_->StartUsingTheme();
519 }
520
417 void ThemeService::SavePackName(const base::FilePath& pack_path) { 521 void ThemeService::SavePackName(const base::FilePath& pack_path) {
418 profile_->GetPrefs()->SetFilePath( 522 profile_->GetPrefs()->SetFilePath(
419 prefs::kCurrentThemePackFilename, pack_path); 523 prefs::kCurrentThemePackFilename, pack_path);
420 } 524 }
421 525
422 void ThemeService::SaveThemeID(const std::string& id) { 526 void ThemeService::SaveThemeID(const std::string& id) {
423 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); 527 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id);
424 } 528 }
425 529
426 void ThemeService::BuildFromExtension(const Extension* extension) { 530 void ThemeService::BuildFromExtension(const Extension* extension) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 566 }
463 567
464 void ThemeService::OnInfobarDisplayed() { 568 void ThemeService::OnInfobarDisplayed() {
465 number_of_infobars_++; 569 number_of_infobars_++;
466 } 570 }
467 571
468 void ThemeService::OnInfobarDestroyed() { 572 void ThemeService::OnInfobarDestroyed() {
469 number_of_infobars_--; 573 number_of_infobars_--;
470 574
471 if (number_of_infobars_ == 0) 575 if (number_of_infobars_ == 0)
472 RemoveUnusedThemes(); 576 RemoveUnusedThemes(false);
473 } 577 }
474 578
475 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { 579 ThemeSyncableService* ThemeService::GetThemeSyncableService() const {
476 return theme_syncable_service_.get(); 580 return theme_syncable_service_.get();
477 } 581 }
OLDNEW
« no previous file with comments | « chrome/browser/themes/theme_service.h ('k') | chrome/browser/themes/theme_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698