| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 #include "ui/native_theme/native_theme.h" | 47 #include "ui/native_theme/native_theme.h" |
| 48 | 48 |
| 49 #if defined(ENABLE_EXTENSIONS) | 49 #if defined(ENABLE_EXTENSIONS) |
| 50 #include "extensions/browser/extension_registry_observer.h" | 50 #include "extensions/browser/extension_registry_observer.h" |
| 51 #endif | 51 #endif |
| 52 | 52 |
| 53 #if defined(ENABLE_SUPERVISED_USERS) | 53 #if defined(ENABLE_SUPERVISED_USERS) |
| 54 #include "chrome/browser/supervised_user/supervised_user_theme.h" | 54 #include "chrome/browser/supervised_user/supervised_user_theme.h" |
| 55 #endif | 55 #endif |
| 56 | 56 |
| 57 #if defined(OS_WIN) |
| 58 #include "ui/base/win/shell.h" |
| 59 #endif |
| 60 |
| 57 using base::UserMetricsAction; | 61 using base::UserMetricsAction; |
| 58 using content::BrowserThread; | 62 using content::BrowserThread; |
| 59 using extensions::Extension; | 63 using extensions::Extension; |
| 60 using extensions::UnloadedExtensionInfo; | 64 using extensions::UnloadedExtensionInfo; |
| 61 using ui::ResourceBundle; | 65 using ui::ResourceBundle; |
| 62 | 66 |
| 63 | 67 |
| 64 // Helpers -------------------------------------------------------------------- | 68 // Helpers -------------------------------------------------------------------- |
| 65 | 69 |
| 66 namespace { | 70 namespace { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 scoped_refptr<CustomThemeSupplier> theme_supplier) { | 406 scoped_refptr<CustomThemeSupplier> theme_supplier) { |
| 403 ClearAllThemeData(); | 407 ClearAllThemeData(); |
| 404 SwapThemeSupplier(theme_supplier); | 408 SwapThemeSupplier(theme_supplier); |
| 405 NotifyThemeChanged(); | 409 NotifyThemeChanged(); |
| 406 } | 410 } |
| 407 | 411 |
| 408 bool ThemeService::ShouldInitWithSystemTheme() const { | 412 bool ThemeService::ShouldInitWithSystemTheme() const { |
| 409 return false; | 413 return false; |
| 410 } | 414 } |
| 411 | 415 |
| 412 SkColor ThemeService::GetDefaultColor(int id, bool incognito) const { | 416 color_utils::HSL ThemeService::GetTint(int id, bool incognito) const { |
| 417 DCHECK(CalledOnValidThread()); |
| 418 |
| 419 color_utils::HSL hsl; |
| 420 if (theme_supplier_ && theme_supplier_->GetTint(id, &hsl)) |
| 421 return hsl; |
| 422 |
| 423 return ThemeProperties::GetDefaultTint(id, incognito); |
| 424 } |
| 425 |
| 426 void ThemeService::ClearAllThemeData() { |
| 427 if (!ready_) |
| 428 return; |
| 429 |
| 430 SwapThemeSupplier(nullptr); |
| 431 |
| 432 // Clear our image cache. |
| 433 FreePlatformCaches(); |
| 434 |
| 435 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); |
| 436 SaveThemeID(kDefaultThemeID); |
| 437 |
| 438 // There should be no more infobars. This may not be the case because of |
| 439 // http://crbug.com/62154 |
| 440 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may |
| 441 // be called as a result of NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED. |
| 442 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 443 FROM_HERE, base::Bind(&ThemeService::RemoveUnusedThemes, |
| 444 weak_ptr_factory_.GetWeakPtr(), true)); |
| 445 } |
| 446 |
| 447 void ThemeService::LoadThemePrefs() { |
| 448 PrefService* prefs = profile_->GetPrefs(); |
| 449 |
| 450 std::string current_id = GetThemeID(); |
| 451 if (current_id == kDefaultThemeID) { |
| 452 #if defined(ENABLE_SUPERVISED_USERS) |
| 453 // Supervised users have a different default theme. |
| 454 if (IsSupervisedUser()) { |
| 455 SetSupervisedUserTheme(); |
| 456 set_ready(); |
| 457 return; |
| 458 } |
| 459 #endif |
| 460 if (ShouldInitWithSystemTheme()) |
| 461 UseSystemTheme(); |
| 462 else |
| 463 UseDefaultTheme(); |
| 464 set_ready(); |
| 465 return; |
| 466 } |
| 467 |
| 468 bool loaded_pack = false; |
| 469 |
| 470 // If we don't have a file pack, we're updating from an old version, or the |
| 471 // pack was created for an alternative MaterialDesignController::Mode. |
| 472 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); |
| 473 if (path != base::FilePath()) { |
| 474 path = path.Append(ui::MaterialDesignController::IsModeMaterial() |
| 475 ? chrome::kThemePackMaterialDesignFilename |
| 476 : chrome::kThemePackFilename); |
| 477 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); |
| 478 loaded_pack = theme_supplier_ != nullptr; |
| 479 } |
| 480 |
| 481 if (loaded_pack) { |
| 482 content::RecordAction(UserMetricsAction("Themes.Loaded")); |
| 483 set_ready(); |
| 484 } |
| 485 // Else: wait for the extension service to be ready so that the theme pack |
| 486 // can be recreated from the extension. |
| 487 } |
| 488 |
| 489 void ThemeService::NotifyThemeChanged() { |
| 490 if (!ready_) |
| 491 return; |
| 492 |
| 493 DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; |
| 494 // Redraw! |
| 495 content::NotificationService* service = |
| 496 content::NotificationService::current(); |
| 497 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
| 498 content::Source<ThemeService>(this), |
| 499 content::NotificationService::NoDetails()); |
| 500 #if defined(OS_MACOSX) |
| 501 NotifyPlatformThemeChanged(); |
| 502 #endif // OS_MACOSX |
| 503 |
| 504 // Notify sync that theme has changed. |
| 505 if (theme_syncable_service_.get()) { |
| 506 theme_syncable_service_->OnThemeChange(); |
| 507 } |
| 508 } |
| 509 |
| 510 #if defined(USE_AURA) |
| 511 void ThemeService::FreePlatformCaches() { |
| 512 // Views (Skia) has no platform image cache to clear. |
| 513 } |
| 514 #endif |
| 515 |
| 516 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const { |
| 517 gfx::Image image = GetImageNamed(id, incognito); |
| 518 if (image.IsEmpty()) |
| 519 return nullptr; |
| 520 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns |
| 521 // its images const. GetImageSkiaNamed() also should but has many callsites. |
| 522 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); |
| 523 } |
| 524 |
| 525 SkColor ThemeService::GetColor(int id, bool incognito) const { |
| 526 DCHECK(CalledOnValidThread()); |
| 527 |
| 528 // For legacy reasons, |theme_supplier_| requires the incognito variants |
| 529 // of color IDs. |
| 530 int theme_supplier_id = id; |
| 531 if (incognito) { |
| 532 if (id == ThemeProperties::COLOR_FRAME) |
| 533 theme_supplier_id = ThemeProperties::COLOR_FRAME_INCOGNITO; |
| 534 else if (id == ThemeProperties::COLOR_FRAME_INACTIVE) |
| 535 theme_supplier_id = ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE; |
| 536 } |
| 537 |
| 538 SkColor color; |
| 539 if (theme_supplier_ && theme_supplier_->GetColor(theme_supplier_id, &color)) |
| 540 return color; |
| 541 |
| 413 // For backward compat with older themes, some newer colors are generated from | 542 // For backward compat with older themes, some newer colors are generated from |
| 414 // older ones if they are missing. | 543 // older ones if they are missing. |
| 415 const int kNtpText = ThemeProperties::COLOR_NTP_TEXT; | 544 const int kNtpText = ThemeProperties::COLOR_NTP_TEXT; |
| 416 const int kLabelBackground = | 545 const int kLabelBackground = |
| 417 ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND; | 546 ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND; |
| 418 switch (id) { | 547 switch (id) { |
| 419 case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON: | 548 case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON: |
| 420 return color_utils::HSLShift( | 549 return color_utils::HSLShift( |
| 421 gfx::kChromeIconGrey, | 550 gfx::kChromeIconGrey, |
| 422 GetTint(ThemeProperties::TINT_BUTTONS, incognito)); | 551 GetTint(ThemeProperties::TINT_BUTTONS, incognito)); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 SkColorGetA(text_color), | 619 SkColorGetA(text_color), |
| 491 (SkColorGetR(text_color) + SkColorGetR(toolbar_color)) / 2, | 620 (SkColorGetR(text_color) + SkColorGetR(toolbar_color)) / 2, |
| 492 (SkColorGetG(text_color) + SkColorGetR(toolbar_color)) / 2, | 621 (SkColorGetG(text_color) + SkColorGetR(toolbar_color)) / 2, |
| 493 (SkColorGetB(text_color) + SkColorGetR(toolbar_color)) / 2); | 622 (SkColorGetB(text_color) + SkColorGetR(toolbar_color)) / 2); |
| 494 } | 623 } |
| 495 } | 624 } |
| 496 | 625 |
| 497 return ThemeProperties::GetDefaultColor(id, incognito); | 626 return ThemeProperties::GetDefaultColor(id, incognito); |
| 498 } | 627 } |
| 499 | 628 |
| 500 color_utils::HSL ThemeService::GetTint(int id, bool incognito) const { | |
| 501 DCHECK(CalledOnValidThread()); | |
| 502 | |
| 503 color_utils::HSL hsl; | |
| 504 if (theme_supplier_ && theme_supplier_->GetTint(id, &hsl)) | |
| 505 return hsl; | |
| 506 | |
| 507 return ThemeProperties::GetDefaultTint(id, incognito); | |
| 508 } | |
| 509 | |
| 510 void ThemeService::ClearAllThemeData() { | |
| 511 if (!ready_) | |
| 512 return; | |
| 513 | |
| 514 SwapThemeSupplier(nullptr); | |
| 515 | |
| 516 // Clear our image cache. | |
| 517 FreePlatformCaches(); | |
| 518 | |
| 519 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); | |
| 520 SaveThemeID(kDefaultThemeID); | |
| 521 | |
| 522 // There should be no more infobars. This may not be the case because of | |
| 523 // http://crbug.com/62154 | |
| 524 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may | |
| 525 // be called as a result of NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED. | |
| 526 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 527 FROM_HERE, base::Bind(&ThemeService::RemoveUnusedThemes, | |
| 528 weak_ptr_factory_.GetWeakPtr(), true)); | |
| 529 } | |
| 530 | |
| 531 void ThemeService::LoadThemePrefs() { | |
| 532 PrefService* prefs = profile_->GetPrefs(); | |
| 533 | |
| 534 std::string current_id = GetThemeID(); | |
| 535 if (current_id == kDefaultThemeID) { | |
| 536 #if defined(ENABLE_SUPERVISED_USERS) | |
| 537 // Supervised users have a different default theme. | |
| 538 if (IsSupervisedUser()) { | |
| 539 SetSupervisedUserTheme(); | |
| 540 set_ready(); | |
| 541 return; | |
| 542 } | |
| 543 #endif | |
| 544 if (ShouldInitWithSystemTheme()) | |
| 545 UseSystemTheme(); | |
| 546 else | |
| 547 UseDefaultTheme(); | |
| 548 set_ready(); | |
| 549 return; | |
| 550 } | |
| 551 | |
| 552 bool loaded_pack = false; | |
| 553 | |
| 554 // If we don't have a file pack, we're updating from an old version, or the | |
| 555 // pack was created for an alternative MaterialDesignController::Mode. | |
| 556 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); | |
| 557 if (path != base::FilePath()) { | |
| 558 path = path.Append(ui::MaterialDesignController::IsModeMaterial() | |
| 559 ? chrome::kThemePackMaterialDesignFilename | |
| 560 : chrome::kThemePackFilename); | |
| 561 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); | |
| 562 loaded_pack = theme_supplier_ != nullptr; | |
| 563 } | |
| 564 | |
| 565 if (loaded_pack) { | |
| 566 content::RecordAction(UserMetricsAction("Themes.Loaded")); | |
| 567 set_ready(); | |
| 568 } | |
| 569 // Else: wait for the extension service to be ready so that the theme pack | |
| 570 // can be recreated from the extension. | |
| 571 } | |
| 572 | |
| 573 void ThemeService::NotifyThemeChanged() { | |
| 574 if (!ready_) | |
| 575 return; | |
| 576 | |
| 577 DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; | |
| 578 // Redraw! | |
| 579 content::NotificationService* service = | |
| 580 content::NotificationService::current(); | |
| 581 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | |
| 582 content::Source<ThemeService>(this), | |
| 583 content::NotificationService::NoDetails()); | |
| 584 #if defined(OS_MACOSX) | |
| 585 NotifyPlatformThemeChanged(); | |
| 586 #endif // OS_MACOSX | |
| 587 | |
| 588 // Notify sync that theme has changed. | |
| 589 if (theme_syncable_service_.get()) { | |
| 590 theme_syncable_service_->OnThemeChange(); | |
| 591 } | |
| 592 } | |
| 593 | |
| 594 #if defined(USE_AURA) | |
| 595 void ThemeService::FreePlatformCaches() { | |
| 596 // Views (Skia) has no platform image cache to clear. | |
| 597 } | |
| 598 #endif | |
| 599 | |
| 600 bool ThemeService::ShouldUseNativeFrame() const { | |
| 601 return false; | |
| 602 } | |
| 603 | |
| 604 bool ThemeService::HasCustomImage(int id) const { | |
| 605 return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ && | |
| 606 theme_supplier_->HasCustomImage(id); | |
| 607 } | |
| 608 | |
| 609 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const { | |
| 610 gfx::Image image = GetImageNamed(id, incognito); | |
| 611 if (image.IsEmpty()) | |
| 612 return nullptr; | |
| 613 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns | |
| 614 // its images const. GetImageSkiaNamed() also should but has many callsites. | |
| 615 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); | |
| 616 } | |
| 617 | |
| 618 SkColor ThemeService::GetColor(int id, bool incognito) const { | |
| 619 DCHECK(CalledOnValidThread()); | |
| 620 | |
| 621 // For legacy reasons, |theme_supplier_| requires the incognito variants | |
| 622 // of color IDs. | |
| 623 int theme_supplier_id = id; | |
| 624 if (incognito) { | |
| 625 if (id == ThemeProperties::COLOR_FRAME) | |
| 626 theme_supplier_id = ThemeProperties::COLOR_FRAME_INCOGNITO; | |
| 627 else if (id == ThemeProperties::COLOR_FRAME_INACTIVE) | |
| 628 theme_supplier_id = ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE; | |
| 629 } | |
| 630 | |
| 631 SkColor color; | |
| 632 if (theme_supplier_ && theme_supplier_->GetColor(theme_supplier_id, &color)) | |
| 633 return color; | |
| 634 | |
| 635 return GetDefaultColor(id, incognito); | |
| 636 } | |
| 637 | |
| 638 int ThemeService::GetDisplayProperty(int id) const { | 629 int ThemeService::GetDisplayProperty(int id) const { |
| 639 int result = 0; | 630 int result = 0; |
| 640 if (theme_supplier_ && theme_supplier_->GetDisplayProperty(id, &result)) { | 631 if (theme_supplier_ && theme_supplier_->GetDisplayProperty(id, &result)) { |
| 641 return result; | 632 return result; |
| 642 } | 633 } |
| 643 | 634 |
| 644 switch (id) { | 635 switch (id) { |
| 645 case ThemeProperties::NTP_BACKGROUND_ALIGNMENT: | 636 case ThemeProperties::NTP_BACKGROUND_ALIGNMENT: |
| 646 return ThemeProperties::ALIGN_CENTER; | 637 return ThemeProperties::ALIGN_CENTER; |
| 647 | 638 |
| 648 case ThemeProperties::NTP_BACKGROUND_TILING: | 639 case ThemeProperties::NTP_BACKGROUND_TILING: |
| 649 return ThemeProperties::NO_REPEAT; | 640 return ThemeProperties::NO_REPEAT; |
| 650 | 641 |
| 651 case ThemeProperties::NTP_LOGO_ALTERNATE: { | 642 case ThemeProperties::NTP_LOGO_ALTERNATE: { |
| 652 if (UsingDefaultTheme() || UsingSystemTheme()) | 643 if (UsingDefaultTheme() || UsingSystemTheme()) |
| 653 return 0; | 644 return 0; |
| 654 if (HasCustomImage(IDR_THEME_NTP_BACKGROUND)) | 645 if (HasCustomImage(IDR_THEME_NTP_BACKGROUND)) |
| 655 return 1; | 646 return 1; |
| 656 return IsColorGrayscale( | 647 return IsColorGrayscale( |
| 657 GetColor(ThemeProperties::COLOR_NTP_BACKGROUND, false)) ? 0 : 1; | 648 GetColor(ThemeProperties::COLOR_NTP_BACKGROUND, false)) ? 0 : 1; |
| 658 } | 649 } |
| 659 | 650 |
| 660 default: | 651 default: |
| 661 return -1; | 652 return -1; |
| 662 } | 653 } |
| 663 } | 654 } |
| 664 | 655 |
| 656 bool ThemeService::ShouldUseNativeFrame() const { |
| 657 if (HasCustomImage(IDR_THEME_FRAME)) |
| 658 return false; |
| 659 #if defined(OS_WIN) |
| 660 return ui::win::IsAeroGlassEnabled(); |
| 661 #else |
| 662 return false; |
| 663 #endif |
| 664 } |
| 665 |
| 666 bool ThemeService::HasCustomImage(int id) const { |
| 667 return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ && |
| 668 theme_supplier_->HasCustomImage(id); |
| 669 } |
| 670 |
| 665 base::RefCountedMemory* ThemeService::GetRawData( | 671 base::RefCountedMemory* ThemeService::GetRawData( |
| 666 int id, | 672 int id, |
| 667 ui::ScaleFactor scale_factor) const { | 673 ui::ScaleFactor scale_factor) const { |
| 668 // Check to see whether we should substitute some images. | 674 // Check to see whether we should substitute some images. |
| 669 int ntp_alternate = GetDisplayProperty(ThemeProperties::NTP_LOGO_ALTERNATE); | 675 int ntp_alternate = GetDisplayProperty(ThemeProperties::NTP_LOGO_ALTERNATE); |
| 670 if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) | 676 if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) |
| 671 id = IDR_PRODUCT_LOGO_WHITE; | 677 id = IDR_PRODUCT_LOGO_WHITE; |
| 672 | 678 |
| 673 base::RefCountedMemory* data = nullptr; | 679 base::RefCountedMemory* data = nullptr; |
| 674 if (theme_supplier_) | 680 if (theme_supplier_) |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 | 800 |
| 795 #if defined(ENABLE_SUPERVISED_USERS) | 801 #if defined(ENABLE_SUPERVISED_USERS) |
| 796 bool ThemeService::IsSupervisedUser() const { | 802 bool ThemeService::IsSupervisedUser() const { |
| 797 return profile_->IsSupervised(); | 803 return profile_->IsSupervised(); |
| 798 } | 804 } |
| 799 | 805 |
| 800 void ThemeService::SetSupervisedUserTheme() { | 806 void ThemeService::SetSupervisedUserTheme() { |
| 801 SetCustomDefaultTheme(new SupervisedUserTheme); | 807 SetCustomDefaultTheme(new SupervisedUserTheme); |
| 802 } | 808 } |
| 803 #endif | 809 #endif |
| OLD | NEW |