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

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