Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/ref_counted_memory.h" | 10 #include "base/memory/ref_counted_memory.h" |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 #include "extensions/browser/extension_registry.h" | 28 #include "extensions/browser/extension_registry.h" |
| 29 #include "extensions/browser/extension_system.h" | 29 #include "extensions/browser/extension_system.h" |
| 30 #include "extensions/browser/uninstall_reason.h" | 30 #include "extensions/browser/uninstall_reason.h" |
| 31 #include "extensions/common/extension.h" | 31 #include "extensions/common/extension.h" |
| 32 #include "extensions/common/extension_set.h" | 32 #include "extensions/common/extension_set.h" |
| 33 #include "grit/theme_resources.h" | 33 #include "grit/theme_resources.h" |
| 34 #include "ui/base/layout.h" | 34 #include "ui/base/layout.h" |
| 35 #include "ui/base/resource/resource_bundle.h" | 35 #include "ui/base/resource/resource_bundle.h" |
| 36 #include "ui/gfx/image/image_skia.h" | 36 #include "ui/gfx/image/image_skia.h" |
| 37 | 37 |
| 38 #if defined(ENABLE_EXTENSIONS) | |
| 39 #include "extensions/browser/extension_registry_observer.h" | |
| 40 #endif | |
| 41 | |
| 38 #if defined(ENABLE_SUPERVISED_USERS) | 42 #if defined(ENABLE_SUPERVISED_USERS) |
| 39 #include "chrome/browser/supervised_user/supervised_user_theme.h" | 43 #include "chrome/browser/supervised_user/supervised_user_theme.h" |
| 40 #endif | 44 #endif |
| 41 | 45 |
| 42 #if defined(OS_WIN) | 46 #if defined(OS_WIN) |
| 43 #include "ui/base/win/shell.h" | 47 #include "ui/base/win/shell.h" |
| 44 #endif | 48 #endif |
| 45 | 49 |
| 46 using base::UserMetricsAction; | 50 using base::UserMetricsAction; |
| 47 using content::BrowserThread; | 51 using content::BrowserThread; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 const int kChannelTolerance = 9; | 93 const int kChannelTolerance = 9; |
| 90 int r = SkColorGetR(color); | 94 int r = SkColorGetR(color); |
| 91 int g = SkColorGetG(color); | 95 int g = SkColorGetG(color); |
| 92 int b = SkColorGetB(color); | 96 int b = SkColorGetB(color); |
| 93 int range = std::max(r, std::max(g, b)) - std::min(r, std::min(g, b)); | 97 int range = std::max(r, std::max(g, b)) - std::min(r, std::min(g, b)); |
| 94 return range < kChannelTolerance; | 98 return range < kChannelTolerance; |
| 95 } | 99 } |
| 96 | 100 |
| 97 } // namespace | 101 } // namespace |
| 98 | 102 |
| 103 #if defined(ENABLE_EXTENSIONS) | |
| 104 class ThemeService::ThemeObserver | |
| 105 : public extensions::ExtensionRegistryObserver { | |
| 106 public: | |
| 107 explicit ThemeObserver(ThemeService* service) : theme_service_(service) { | |
| 108 extensions::ExtensionRegistry::Get(theme_service_->profile_) | |
| 109 ->AddObserver(this); | |
| 110 } | |
|
not at google - send to devlin
2015/03/13 17:01:44
Could you separate all of these methods with blank
| |
| 111 ~ThemeObserver() override { | |
| 112 extensions::ExtensionRegistry::Get(theme_service_->profile_) | |
| 113 ->RemoveObserver(this); | |
| 114 } | |
| 115 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, | |
| 116 const extensions::Extension* extension, | |
| 117 bool is_update, | |
| 118 bool from_ephemeral, | |
| 119 const std::string& old_name) override { | |
| 120 if (extension->is_theme()) { | |
| 121 // The theme may be initially disabled. Wait till it is loaded (if ever). | |
| 122 theme_service_->installed_pending_load_id_ = extension->id(); | |
| 123 } | |
| 124 } | |
| 125 void OnExtensionLoaded(content::BrowserContext* browser_context, | |
| 126 const extensions::Extension* extension) override { | |
| 127 if (extension->is_theme() && | |
| 128 theme_service_->installed_pending_load_id_ != kDefaultThemeID && | |
| 129 theme_service_->installed_pending_load_id_ == extension->id()) { | |
| 130 theme_service_->SetTheme(extension); | |
| 131 } | |
| 132 theme_service_->installed_pending_load_id_ = kDefaultThemeID; | |
| 133 } | |
| 134 void OnExtensionUnloaded( | |
| 135 content::BrowserContext* browser_context, | |
| 136 const extensions::Extension* extension, | |
| 137 extensions::UnloadedExtensionInfo::Reason reason) override { | |
| 138 if (reason != extensions::UnloadedExtensionInfo::REASON_UPDATE && | |
| 139 reason != extensions::UnloadedExtensionInfo::REASON_LOCK_ALL && | |
| 140 extension->is_theme() && | |
| 141 extension->id() == theme_service_->GetThemeID()) { | |
| 142 theme_service_->UseDefaultTheme(); | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 private: | |
| 147 ThemeService* theme_service_; | |
| 148 }; | |
| 149 #endif // defined(ENABLE_EXTENSIONS) | |
| 150 | |
| 99 ThemeService::ThemeService() | 151 ThemeService::ThemeService() |
| 100 : ready_(false), | 152 : ready_(false), |
| 101 rb_(ResourceBundle::GetSharedInstance()), | 153 rb_(ResourceBundle::GetSharedInstance()), |
| 102 profile_(NULL), | 154 profile_(nullptr), |
| 103 installed_pending_load_id_(kDefaultThemeID), | 155 installed_pending_load_id_(kDefaultThemeID), |
| 104 number_of_infobars_(0), | 156 number_of_infobars_(0), |
| 105 weak_ptr_factory_(this) { | 157 weak_ptr_factory_(this) { |
| 106 } | 158 } |
| 107 | 159 |
| 108 ThemeService::~ThemeService() { | 160 ThemeService::~ThemeService() { |
| 109 FreePlatformCaches(); | 161 FreePlatformCaches(); |
| 110 } | 162 } |
| 111 | 163 |
| 112 void ThemeService::Init(Profile* profile) { | 164 void ThemeService::Init(Profile* profile) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 139 return false; | 191 return false; |
| 140 } | 192 } |
| 141 | 193 |
| 142 bool ThemeService::UsingSystemTheme() const { | 194 bool ThemeService::UsingSystemTheme() const { |
| 143 return UsingDefaultTheme(); | 195 return UsingDefaultTheme(); |
| 144 } | 196 } |
| 145 | 197 |
| 146 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const { | 198 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const { |
| 147 gfx::Image image = GetImageNamed(id); | 199 gfx::Image image = GetImageNamed(id); |
| 148 if (image.IsEmpty()) | 200 if (image.IsEmpty()) |
| 149 return NULL; | 201 return nullptr; |
| 150 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns | 202 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns |
| 151 // its images const. GetImageSkiaNamed() also should but has many callsites. | 203 // its images const. GetImageSkiaNamed() also should but has many callsites. |
| 152 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); | 204 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); |
| 153 } | 205 } |
| 154 | 206 |
| 155 SkColor ThemeService::GetColor(int id) const { | 207 SkColor ThemeService::GetColor(int id) const { |
| 156 DCHECK(CalledOnValidThread()); | 208 DCHECK(CalledOnValidThread()); |
| 157 SkColor color; | 209 SkColor color; |
| 158 if (theme_supplier_.get() && theme_supplier_->GetColor(id, &color)) | 210 if (theme_supplier_.get() && theme_supplier_->GetColor(id, &color)) |
| 159 return color; | 211 return color; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 } | 293 } |
| 242 | 294 |
| 243 base::RefCountedMemory* ThemeService::GetRawData( | 295 base::RefCountedMemory* ThemeService::GetRawData( |
| 244 int id, | 296 int id, |
| 245 ui::ScaleFactor scale_factor) const { | 297 ui::ScaleFactor scale_factor) const { |
| 246 // Check to see whether we should substitute some images. | 298 // Check to see whether we should substitute some images. |
| 247 int ntp_alternate = GetDisplayProperty(Properties::NTP_LOGO_ALTERNATE); | 299 int ntp_alternate = GetDisplayProperty(Properties::NTP_LOGO_ALTERNATE); |
| 248 if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) | 300 if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) |
| 249 id = IDR_PRODUCT_LOGO_WHITE; | 301 id = IDR_PRODUCT_LOGO_WHITE; |
| 250 | 302 |
| 251 base::RefCountedMemory* data = NULL; | 303 base::RefCountedMemory* data = nullptr; |
| 252 if (theme_supplier_.get()) | 304 if (theme_supplier_.get()) |
| 253 data = theme_supplier_->GetRawData(id, scale_factor); | 305 data = theme_supplier_->GetRawData(id, scale_factor); |
| 254 if (!data) | 306 if (!data) |
| 255 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); | 307 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); |
| 256 | 308 |
| 257 return data; | 309 return data; |
| 258 } | 310 } |
| 259 | 311 |
| 312 void ThemeService::Shutdown() { | |
| 313 #if defined(ENABLE_EXTENSIONS) | |
| 314 theme_observer_.reset(); | |
| 315 #endif | |
| 316 } | |
| 317 | |
| 260 void ThemeService::Observe(int type, | 318 void ThemeService::Observe(int type, |
| 261 const content::NotificationSource& source, | 319 const content::NotificationSource& source, |
| 262 const content::NotificationDetails& details) { | 320 const content::NotificationDetails& details) { |
| 263 using content::Details; | 321 using content::Details; |
| 264 switch (type) { | 322 switch (type) { |
| 265 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: | 323 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: |
| 266 registrar_.Remove(this, | 324 registrar_.Remove(this, |
| 267 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, | 325 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, |
| 268 content::Source<Profile>(profile_)); | 326 content::Source<Profile>(profile_)); |
| 269 OnExtensionServiceReady(); | 327 OnExtensionServiceReady(); |
| 270 break; | 328 break; |
| 271 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: { | |
| 272 // The theme may be initially disabled. Wait till it is loaded (if ever). | |
| 273 Details<const extensions::InstalledExtensionInfo> installed_details( | |
| 274 details); | |
| 275 if (installed_details->extension->is_theme()) | |
| 276 installed_pending_load_id_ = installed_details->extension->id(); | |
| 277 break; | |
| 278 } | |
| 279 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { | |
| 280 const Extension* extension = Details<const Extension>(details).ptr(); | |
| 281 if (extension->is_theme() && | |
| 282 installed_pending_load_id_ != kDefaultThemeID && | |
| 283 installed_pending_load_id_ == extension->id()) { | |
| 284 SetTheme(extension); | |
| 285 } | |
| 286 installed_pending_load_id_ = kDefaultThemeID; | |
| 287 break; | |
| 288 } | |
| 289 case extensions::NOTIFICATION_EXTENSION_ENABLED: { | 329 case extensions::NOTIFICATION_EXTENSION_ENABLED: { |
| 290 const Extension* extension = Details<const Extension>(details).ptr(); | 330 const Extension* extension = Details<const Extension>(details).ptr(); |
| 291 if (extension->is_theme()) | 331 if (extension->is_theme()) |
| 292 SetTheme(extension); | 332 SetTheme(extension); |
| 293 break; | 333 break; |
| 294 } | 334 } |
| 295 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { | 335 default: |
| 296 Details<const UnloadedExtensionInfo> unloaded_details(details); | 336 NOTREACHED(); |
| 297 if (unloaded_details->reason != UnloadedExtensionInfo::REASON_UPDATE && | |
| 298 unloaded_details->reason != UnloadedExtensionInfo::REASON_LOCK_ALL && | |
| 299 unloaded_details->extension->is_theme() && | |
| 300 unloaded_details->extension->id() == GetThemeID()) { | |
| 301 UseDefaultTheme(); | |
| 302 } | |
| 303 break; | |
| 304 } | |
| 305 } | 337 } |
| 306 } | 338 } |
| 307 | 339 |
| 308 void ThemeService::SetTheme(const Extension* extension) { | 340 void ThemeService::SetTheme(const Extension* extension) { |
| 309 DCHECK(extension->is_theme()); | 341 DCHECK(extension->is_theme()); |
| 310 ExtensionService* service = | 342 ExtensionService* service = |
| 311 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 343 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 312 if (!service->IsExtensionEnabled(extension->id())) { | 344 if (!service->IsExtensionEnabled(extension->id())) { |
| 313 // |extension| is disabled when reverting to the previous theme via an | 345 // |extension| is disabled when reverting to the previous theme via an |
| 314 // infobar. | 346 // infobar. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 } | 413 } |
| 382 } | 414 } |
| 383 } | 415 } |
| 384 // TODO: Garbage collect all unused themes. This method misses themes which | 416 // TODO: Garbage collect all unused themes. This method misses themes which |
| 385 // are installed but not loaded because they are blacklisted by a management | 417 // are installed but not loaded because they are blacklisted by a management |
| 386 // policy provider. | 418 // policy provider. |
| 387 | 419 |
| 388 for (size_t i = 0; i < remove_list.size(); ++i) { | 420 for (size_t i = 0; i < remove_list.size(); ++i) { |
| 389 service->UninstallExtension(remove_list[i], | 421 service->UninstallExtension(remove_list[i], |
| 390 extensions::UNINSTALL_REASON_ORPHANED_THEME, | 422 extensions::UNINSTALL_REASON_ORPHANED_THEME, |
| 391 base::Bind(&base::DoNothing), | 423 base::Bind(&base::DoNothing), nullptr); |
| 392 NULL); | |
| 393 } | 424 } |
| 394 } | 425 } |
| 395 | 426 |
| 396 void ThemeService::UseDefaultTheme() { | 427 void ThemeService::UseDefaultTheme() { |
| 397 if (ready_) | 428 if (ready_) |
| 398 content::RecordAction(UserMetricsAction("Themes_Reset")); | 429 content::RecordAction(UserMetricsAction("Themes_Reset")); |
| 399 #if defined(ENABLE_SUPERVISED_USERS) | 430 #if defined(ENABLE_SUPERVISED_USERS) |
| 400 if (IsSupervisedUser()) { | 431 if (IsSupervisedUser()) { |
| 401 SetSupervisedUserTheme(); | 432 SetSupervisedUserTheme(); |
| 402 return; | 433 return; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 427 if (theme_supplier_.get() && theme_supplier_->GetTint(id, &hsl)) | 458 if (theme_supplier_.get() && theme_supplier_->GetTint(id, &hsl)) |
| 428 return hsl; | 459 return hsl; |
| 429 | 460 |
| 430 return ThemeProperties::GetDefaultTint(id); | 461 return ThemeProperties::GetDefaultTint(id); |
| 431 } | 462 } |
| 432 | 463 |
| 433 void ThemeService::ClearAllThemeData() { | 464 void ThemeService::ClearAllThemeData() { |
| 434 if (!ready_) | 465 if (!ready_) |
| 435 return; | 466 return; |
| 436 | 467 |
| 437 SwapThemeSupplier(NULL); | 468 SwapThemeSupplier(nullptr); |
| 438 | 469 |
| 439 // Clear our image cache. | 470 // Clear our image cache. |
| 440 FreePlatformCaches(); | 471 FreePlatformCaches(); |
| 441 | 472 |
| 442 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); | 473 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); |
| 443 SaveThemeID(kDefaultThemeID); | 474 SaveThemeID(kDefaultThemeID); |
| 444 | 475 |
| 445 // There should be no more infobars. This may not be the case because of | 476 // There should be no more infobars. This may not be the case because of |
| 446 // http://crbug.com/62154 | 477 // http://crbug.com/62154 |
| 447 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may | 478 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 472 set_ready(); | 503 set_ready(); |
| 473 return; | 504 return; |
| 474 } | 505 } |
| 475 | 506 |
| 476 bool loaded_pack = false; | 507 bool loaded_pack = false; |
| 477 | 508 |
| 478 // If we don't have a file pack, we're updating from an old version. | 509 // If we don't have a file pack, we're updating from an old version. |
| 479 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); | 510 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); |
| 480 if (path != base::FilePath()) { | 511 if (path != base::FilePath()) { |
| 481 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); | 512 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); |
| 482 loaded_pack = theme_supplier_.get() != NULL; | 513 loaded_pack = theme_supplier_.get() != nullptr; |
| 483 } | 514 } |
| 484 | 515 |
| 485 if (loaded_pack) { | 516 if (loaded_pack) { |
| 486 content::RecordAction(UserMetricsAction("Themes.Loaded")); | 517 content::RecordAction(UserMetricsAction("Themes.Loaded")); |
| 487 set_ready(); | 518 set_ready(); |
| 488 } | 519 } |
| 489 // Else: wait for the extension service to be ready so that the theme pack | 520 // Else: wait for the extension service to be ready so that the theme pack |
| 490 // can be recreated from the extension. | 521 // can be recreated from the extension. |
| 491 } | 522 } |
| 492 | 523 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 522 // If the ThemeService is not ready yet, the custom theme data pack needs to | 553 // If the ThemeService is not ready yet, the custom theme data pack needs to |
| 523 // be recreated from the extension. | 554 // be recreated from the extension. |
| 524 MigrateTheme(); | 555 MigrateTheme(); |
| 525 set_ready(); | 556 set_ready(); |
| 526 | 557 |
| 527 // Send notification in case anyone requested data and cached it when the | 558 // Send notification in case anyone requested data and cached it when the |
| 528 // theme service was not ready yet. | 559 // theme service was not ready yet. |
| 529 NotifyThemeChanged(); | 560 NotifyThemeChanged(); |
| 530 } | 561 } |
| 531 | 562 |
| 532 registrar_.Add( | 563 #if defined(ENABLE_EXTENSIONS) |
| 533 this, | 564 theme_observer_.reset(new ThemeObserver(this)); |
| 534 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, | 565 #endif |
| 535 content::Source<Profile>(profile_)); | 566 |
| 536 registrar_.Add(this, | |
| 537 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | |
| 538 content::Source<Profile>(profile_)); | |
| 539 registrar_.Add(this, | 567 registrar_.Add(this, |
| 540 extensions::NOTIFICATION_EXTENSION_ENABLED, | 568 extensions::NOTIFICATION_EXTENSION_ENABLED, |
| 541 content::Source<Profile>(profile_)); | 569 content::Source<Profile>(profile_)); |
| 542 registrar_.Add(this, | |
| 543 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | |
| 544 content::Source<Profile>(profile_)); | |
| 545 | 570 |
| 546 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | 571 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 547 base::Bind(&ThemeService::RemoveUnusedThemes, | 572 base::Bind(&ThemeService::RemoveUnusedThemes, |
| 548 weak_ptr_factory_.GetWeakPtr(), | 573 weak_ptr_factory_.GetWeakPtr(), |
| 549 false), | 574 false), |
| 550 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); | 575 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); |
| 551 } | 576 } |
| 552 | 577 |
| 553 void ThemeService::MigrateTheme() { | 578 void ThemeService::MigrateTheme() { |
| 554 // TODO(erg): We need to pop up a dialog informing the user that their | 579 // TODO(erg): We need to pop up a dialog informing the user that their |
| 555 // theme is being migrated. | 580 // theme is being migrated. |
| 556 ExtensionService* service = | 581 ExtensionService* service = |
| 557 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 582 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 558 const Extension* extension = service ? | 583 const Extension* extension = |
| 559 service->GetExtensionById(GetThemeID(), false) : NULL; | 584 service ? service->GetExtensionById(GetThemeID(), false) : nullptr; |
| 560 if (extension) { | 585 if (extension) { |
| 561 DLOG(ERROR) << "Migrating theme"; | 586 DLOG(ERROR) << "Migrating theme"; |
| 562 BuildFromExtension(extension); | 587 BuildFromExtension(extension); |
| 563 content::RecordAction(UserMetricsAction("Themes.Migrated")); | 588 content::RecordAction(UserMetricsAction("Themes.Migrated")); |
| 564 } else { | 589 } else { |
| 565 DLOG(ERROR) << "Theme is mysteriously gone."; | 590 DLOG(ERROR) << "Theme is mysteriously gone."; |
| 566 ClearAllThemeData(); | 591 ClearAllThemeData(); |
| 567 content::RecordAction(UserMetricsAction("Themes.Gone")); | 592 content::RecordAction(UserMetricsAction("Themes.Gone")); |
| 568 } | 593 } |
| 569 } | 594 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 void ThemeService::OnInfobarDestroyed() { | 654 void ThemeService::OnInfobarDestroyed() { |
| 630 number_of_infobars_--; | 655 number_of_infobars_--; |
| 631 | 656 |
| 632 if (number_of_infobars_ == 0) | 657 if (number_of_infobars_ == 0) |
| 633 RemoveUnusedThemes(false); | 658 RemoveUnusedThemes(false); |
| 634 } | 659 } |
| 635 | 660 |
| 636 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { | 661 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { |
| 637 return theme_syncable_service_.get(); | 662 return theme_syncable_service_.get(); |
| 638 } | 663 } |
| OLD | NEW |