| 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 "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/sequenced_task_runner.h" | 9 #include "base/sequenced_task_runner.h" |
| 10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 217 } |
| 218 | 218 |
| 219 ThemeService::~ThemeService() { | 219 ThemeService::~ThemeService() { |
| 220 FreePlatformCaches(); | 220 FreePlatformCaches(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void ThemeService::Init(Profile* profile) { | 223 void ThemeService::Init(Profile* profile) { |
| 224 DCHECK(CalledOnValidThread()); | 224 DCHECK(CalledOnValidThread()); |
| 225 profile_ = profile; | 225 profile_ = profile; |
| 226 | 226 |
| 227 // Listen to EXTENSION_LOADED instead of EXTENSION_INSTALLED because |
| 228 // the extension cannot yet be found via GetExtensionById() if it is |
| 229 // installed but not loaded (which may confuse listeners to |
| 230 // BROWSER_THEME_CHANGED). |
| 231 registrar_.Add(this, |
| 232 chrome::NOTIFICATION_EXTENSION_LOADED, |
| 233 content::Source<Profile>(profile_)); |
| 234 |
| 227 LoadThemePrefs(); | 235 LoadThemePrefs(); |
| 228 | 236 |
| 229 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); | 237 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); |
| 230 } | 238 } |
| 231 | 239 |
| 232 gfx::Image ThemeService::GetImageNamed(int id) const { | 240 gfx::Image ThemeService::GetImageNamed(int id) const { |
| 233 DCHECK(CalledOnValidThread()); | 241 DCHECK(CalledOnValidThread()); |
| 234 | 242 |
| 235 const gfx::Image* image = NULL; | 243 const gfx::Image* image = NULL; |
| 236 | 244 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 343 } |
| 336 | 344 |
| 337 void ThemeService::SetTheme(const Extension* extension) { | 345 void ThemeService::SetTheme(const Extension* extension) { |
| 338 // Clear our image cache. | 346 // Clear our image cache. |
| 339 FreePlatformCaches(); | 347 FreePlatformCaches(); |
| 340 | 348 |
| 341 DCHECK(extension); | 349 DCHECK(extension); |
| 342 DCHECK(extension->is_theme()); | 350 DCHECK(extension->is_theme()); |
| 343 | 351 |
| 344 BuildFromExtension(extension); | 352 BuildFromExtension(extension); |
| 345 SaveThemeIDForProfile(profile_, extension->id()); | 353 SaveThemeID(extension->id()); |
| 346 | 354 |
| 347 NotifyThemeChanged(); | 355 NotifyThemeChanged(); |
| 348 content::RecordAction(UserMetricsAction("Themes_Installed")); | 356 content::RecordAction(UserMetricsAction("Themes_Installed")); |
| 349 } | 357 } |
| 350 | 358 |
| 359 void ThemeService::RemoveUnusedThemes() { |
| 360 if (!profile_) |
| 361 return; |
| 362 ExtensionService* service = profile_->GetExtensionService(); |
| 363 if (!service) |
| 364 return; |
| 365 std::string current_theme = GetThemeID(); |
| 366 std::vector<std::string> remove_list; |
| 367 const ExtensionSet* extensions = service->extensions(); |
| 368 for (ExtensionSet::const_iterator it = extensions->begin(); |
| 369 it != extensions->end(); ++it) { |
| 370 if ((*it)->is_theme() && (*it)->id() != current_theme) { |
| 371 remove_list.push_back((*it)->id()); |
| 372 } |
| 373 } |
| 374 for (size_t i = 0; i < remove_list.size(); ++i) |
| 375 service->UninstallExtension(remove_list[i], false, NULL); |
| 376 } |
| 377 |
| 351 void ThemeService::UseDefaultTheme() { | 378 void ThemeService::UseDefaultTheme() { |
| 352 ClearAllThemeData(); | 379 ClearAllThemeData(); |
| 353 NotifyThemeChanged(); | 380 NotifyThemeChanged(); |
| 354 content::RecordAction(UserMetricsAction("Themes_Reset")); | 381 content::RecordAction(UserMetricsAction("Themes_Reset")); |
| 355 } | 382 } |
| 356 | 383 |
| 357 void ThemeService::SetNativeTheme() { | 384 void ThemeService::SetNativeTheme() { |
| 358 UseDefaultTheme(); | 385 UseDefaultTheme(); |
| 359 } | 386 } |
| 360 | 387 |
| 361 bool ThemeService::UsingDefaultTheme() const { | 388 bool ThemeService::UsingDefaultTheme() const { |
| 362 std::string id = GetThemeID(); | 389 std::string id = GetThemeID(); |
| 363 return id == ThemeService::kDefaultThemeID || | 390 return id == ThemeService::kDefaultThemeID || |
| 364 id == kDefaultThemeGalleryID; | 391 id == kDefaultThemeGalleryID; |
| 365 } | 392 } |
| 366 | 393 |
| 367 bool ThemeService::UsingNativeTheme() const { | 394 bool ThemeService::UsingNativeTheme() const { |
| 368 return UsingDefaultTheme(); | 395 return UsingDefaultTheme(); |
| 369 } | 396 } |
| 370 | 397 |
| 371 void ThemeService::OnInfobarDisplayed() { | 398 std::string ThemeService::GetThemeID() const { |
| 372 number_of_infobars_++; | 399 return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); |
| 373 } | |
| 374 | |
| 375 void ThemeService::OnInfobarDestroyed() { | |
| 376 number_of_infobars_--; | |
| 377 | |
| 378 if (number_of_infobars_ == 0) | |
| 379 RemoveUnusedThemesForProfile(profile_); | |
| 380 } | 400 } |
| 381 | 401 |
| 382 // static | 402 // static |
| 383 std::string ThemeService::GetThemeIDForProfile(Profile* profile) { | |
| 384 return profile->GetPrefs()->GetString(prefs::kCurrentThemeID); | |
| 385 } | |
| 386 | |
| 387 // static | |
| 388 void ThemeService::SaveThemeIDForProfile( | |
| 389 Profile* profile, | |
| 390 const std::string& id) { | |
| 391 profile->GetPrefs()->SetString(prefs::kCurrentThemeID, id); | |
| 392 } | |
| 393 | |
| 394 // static | |
| 395 void ThemeService::RemoveUnusedThemesForProfile(Profile* profile) { | |
| 396 ExtensionService* extension_service = | |
| 397 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
| 398 if (!extension_service) | |
| 399 return; | |
| 400 std::string current_theme = GetThemeIDForProfile(profile); | |
| 401 std::vector<std::string> remove_list; | |
| 402 const ExtensionSet* extensions = extension_service->extensions(); | |
| 403 for (ExtensionSet::const_iterator it = extensions->begin(); | |
| 404 it != extensions->end(); ++it) { | |
| 405 if ((*it)->is_theme() && (*it)->id() != current_theme) { | |
| 406 remove_list.push_back((*it)->id()); | |
| 407 } | |
| 408 } | |
| 409 for (size_t i = 0; i < remove_list.size(); ++i) | |
| 410 extension_service->UninstallExtension(remove_list[i], false, NULL); | |
| 411 } | |
| 412 | |
| 413 std::string ThemeService::GetThemeID() const { | |
| 414 return GetThemeIDForProfile(profile_); | |
| 415 } | |
| 416 | |
| 417 // static | |
| 418 std::string ThemeService::AlignmentToString(int alignment) { | 403 std::string ThemeService::AlignmentToString(int alignment) { |
| 419 // Convert from an AlignmentProperty back into a string. | 404 // Convert from an AlignmentProperty back into a string. |
| 420 std::string vertical_string(kAlignmentCenter); | 405 std::string vertical_string(kAlignmentCenter); |
| 421 std::string horizontal_string(kAlignmentCenter); | 406 std::string horizontal_string(kAlignmentCenter); |
| 422 | 407 |
| 423 if (alignment & ThemeService::ALIGN_TOP) | 408 if (alignment & ThemeService::ALIGN_TOP) |
| 424 vertical_string = kAlignmentTop; | 409 vertical_string = kAlignmentTop; |
| 425 else if (alignment & ThemeService::ALIGN_BOTTOM) | 410 else if (alignment & ThemeService::ALIGN_BOTTOM) |
| 426 vertical_string = kAlignmentBottom; | 411 vertical_string = kAlignmentBottom; |
| 427 | 412 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 | 584 |
| 600 return GetDefaultTint(id); | 585 return GetDefaultTint(id); |
| 601 } | 586 } |
| 602 | 587 |
| 603 void ThemeService::ClearAllThemeData() { | 588 void ThemeService::ClearAllThemeData() { |
| 604 // Clear our image cache. | 589 // Clear our image cache. |
| 605 FreePlatformCaches(); | 590 FreePlatformCaches(); |
| 606 theme_pack_ = NULL; | 591 theme_pack_ = NULL; |
| 607 | 592 |
| 608 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); | 593 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); |
| 609 SaveThemeIDForProfile(profile_, kDefaultThemeID); | 594 SaveThemeID(kDefaultThemeID); |
| 610 } | 595 } |
| 611 | 596 |
| 612 void ThemeService::LoadThemePrefs() { | 597 void ThemeService::LoadThemePrefs() { |
| 613 PrefService* prefs = profile_->GetPrefs(); | 598 PrefService* prefs = profile_->GetPrefs(); |
| 614 | 599 |
| 615 std::string current_id = GetThemeID(); | 600 std::string current_id = GetThemeID(); |
| 616 if (current_id != kDefaultThemeID) { | 601 if (current_id != kDefaultThemeID) { |
| 617 bool loaded_pack = false; | 602 bool loaded_pack = false; |
| 618 | 603 |
| 619 // If we don't have a file pack, we're updating from an old version. | 604 // If we don't have a file pack, we're updating from an old version. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 theme_syncable_service_->OnThemeChange(); | 649 theme_syncable_service_->OnThemeChange(); |
| 665 } | 650 } |
| 666 } | 651 } |
| 667 | 652 |
| 668 #if defined(OS_WIN) || defined(USE_AURA) | 653 #if defined(OS_WIN) || defined(USE_AURA) |
| 669 void ThemeService::FreePlatformCaches() { | 654 void ThemeService::FreePlatformCaches() { |
| 670 // Views (Skia) has no platform image cache to clear. | 655 // Views (Skia) has no platform image cache to clear. |
| 671 } | 656 } |
| 672 #endif | 657 #endif |
| 673 | 658 |
| 659 void ThemeService::Observe(int type, |
| 660 const content::NotificationSource& source, |
| 661 const content::NotificationDetails& details) { |
| 662 DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED); |
| 663 const Extension* extension = content::Details<const Extension>(details).ptr(); |
| 664 if (!extension->is_theme()) { |
| 665 return; |
| 666 } |
| 667 SetTheme(extension); |
| 668 } |
| 669 |
| 674 void ThemeService::SavePackName(const FilePath& pack_path) { | 670 void ThemeService::SavePackName(const FilePath& pack_path) { |
| 675 profile_->GetPrefs()->SetFilePath( | 671 profile_->GetPrefs()->SetFilePath( |
| 676 prefs::kCurrentThemePackFilename, pack_path); | 672 prefs::kCurrentThemePackFilename, pack_path); |
| 677 } | 673 } |
| 678 | 674 |
| 675 void ThemeService::SaveThemeID(const std::string& id) { |
| 676 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); |
| 677 } |
| 678 |
| 679 void ThemeService::BuildFromExtension(const Extension* extension) { | 679 void ThemeService::BuildFromExtension(const Extension* extension) { |
| 680 scoped_refptr<BrowserThemePack> pack( | 680 scoped_refptr<BrowserThemePack> pack( |
| 681 BrowserThemePack::BuildFromExtension(extension)); | 681 BrowserThemePack::BuildFromExtension(extension)); |
| 682 if (!pack.get()) { | 682 if (!pack.get()) { |
| 683 // TODO(erg): We've failed to install the theme; perhaps we should tell the | 683 // TODO(erg): We've failed to install the theme; perhaps we should tell the |
| 684 // user? http://crbug.com/34780 | 684 // user? http://crbug.com/34780 |
| 685 LOG(ERROR) << "Could not load theme."; | 685 LOG(ERROR) << "Could not load theme."; |
| 686 return; | 686 return; |
| 687 } | 687 } |
| 688 | 688 |
| 689 ExtensionService* service = | 689 ExtensionService* service = |
| 690 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 690 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 691 if (!service) | 691 if (!service) |
| 692 return; | 692 return; |
| 693 | 693 |
| 694 // Write the packed file to disk. | 694 // Write the packed file to disk. |
| 695 FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); | 695 FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); |
| 696 service->GetFileTaskRunner()->PostTask( | 696 service->GetFileTaskRunner()->PostTask( |
| 697 FROM_HERE, | 697 FROM_HERE, |
| 698 base::Bind(&WritePackToDiskCallback, pack, pack_path)); | 698 base::Bind(&WritePackToDiskCallback, pack, pack_path)); |
| 699 | 699 |
| 700 SavePackName(pack_path); | 700 SavePackName(pack_path); |
| 701 theme_pack_ = pack; | 701 theme_pack_ = pack; |
| 702 } | 702 } |
| 703 | 703 |
| 704 void ThemeService::OnInfobarDisplayed() { |
| 705 number_of_infobars_++; |
| 706 } |
| 707 |
| 708 void ThemeService::OnInfobarDestroyed() { |
| 709 number_of_infobars_--; |
| 710 |
| 711 if (number_of_infobars_ == 0) |
| 712 RemoveUnusedThemes(); |
| 713 } |
| 714 |
| 704 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { | 715 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { |
| 705 return theme_syncable_service_.get(); | 716 return theme_syncable_service_.get(); |
| 706 } | 717 } |
| OLD | NEW |