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