| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/memory/ref_counted_memory.h" | 14 #include "base/memory/ref_counted_memory.h" |
| 15 #include "base/metrics/user_metrics.h" | 15 #include "base/metrics/user_metrics.h" |
| 16 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
| 17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/task_scheduler/post_task.h" | |
| 21 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 22 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 23 #include "chrome/browser/chrome_notification_types.h" | 22 #include "chrome/browser/chrome_notification_types.h" |
| 24 #include "chrome/browser/extensions/extension_service.h" | 23 #include "chrome/browser/extensions/extension_service.h" |
| 25 #include "chrome/browser/extensions/theme_installed_infobar_delegate.h" | |
| 26 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 27 #include "chrome/browser/themes/browser_theme_pack.h" | 25 #include "chrome/browser/themes/browser_theme_pack.h" |
| 28 #include "chrome/browser/themes/custom_theme_supplier.h" | 26 #include "chrome/browser/themes/custom_theme_supplier.h" |
| 29 #include "chrome/browser/themes/theme_properties.h" | 27 #include "chrome/browser/themes/theme_properties.h" |
| 30 #include "chrome/browser/themes/theme_service_factory.h" | 28 #include "chrome/browser/themes/theme_service_factory.h" |
| 31 #include "chrome/browser/themes/theme_syncable_service.h" | 29 #include "chrome/browser/themes/theme_syncable_service.h" |
| 32 #include "chrome/common/chrome_constants.h" | 30 #include "chrome/common/chrome_constants.h" |
| 33 #include "chrome/common/features.h" | 31 #include "chrome/common/features.h" |
| 34 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
| 35 #include "chrome/grit/theme_resources.h" | 33 #include "chrome/grit/theme_resources.h" |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 switch (type) { | 255 switch (type) { |
| 258 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: | 256 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: |
| 259 registrar_.Remove(this, | 257 registrar_.Remove(this, |
| 260 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, | 258 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, |
| 261 content::Source<Profile>(profile_)); | 259 content::Source<Profile>(profile_)); |
| 262 OnExtensionServiceReady(); | 260 OnExtensionServiceReady(); |
| 263 break; | 261 break; |
| 264 case extensions::NOTIFICATION_EXTENSION_ENABLED: { | 262 case extensions::NOTIFICATION_EXTENSION_ENABLED: { |
| 265 const Extension* extension = Details<const Extension>(details).ptr(); | 263 const Extension* extension = Details<const Extension>(details).ptr(); |
| 266 if (extension->is_theme()) | 264 if (extension->is_theme()) |
| 267 DoSetTheme(extension, true); | 265 SetTheme(extension); |
| 268 break; | 266 break; |
| 269 } | 267 } |
| 270 default: | 268 default: |
| 271 NOTREACHED(); | 269 NOTREACHED(); |
| 272 } | 270 } |
| 273 } | 271 } |
| 274 | 272 |
| 275 void ThemeService::SetTheme(const Extension* extension) { | 273 void ThemeService::SetTheme(const Extension* extension) { |
| 276 DoSetTheme(extension, false); | |
| 277 } | |
| 278 | |
| 279 void ThemeService::RevertToTheme(const Extension* extension) { | |
| 280 DCHECK(extension->is_theme()); | 274 DCHECK(extension->is_theme()); |
| 281 ExtensionService* service = | 275 ExtensionService* service = |
| 282 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 276 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 283 DCHECK(!service->IsExtensionEnabled(extension->id())); | 277 if (!service->IsExtensionEnabled(extension->id())) { |
| 284 // |extension| is disabled when reverting to the previous theme via an | 278 // |extension| is disabled when reverting to the previous theme via an |
| 285 // infobar. | 279 // infobar. |
| 286 service->EnableExtension(extension->id()); | 280 service->EnableExtension(extension->id()); |
| 287 // Enabling the extension will call back to SetTheme(). | 281 // Enabling the extension will call back to SetTheme(). |
| 282 return; |
| 283 } |
| 284 |
| 285 std::string previous_theme_id = GetThemeID(); |
| 286 |
| 287 // Clear our image cache. |
| 288 FreePlatformCaches(); |
| 289 |
| 290 BuildFromExtension(extension); |
| 291 SaveThemeID(extension->id()); |
| 292 |
| 293 NotifyThemeChanged(); |
| 294 base::RecordAction(UserMetricsAction("Themes_Installed")); |
| 295 |
| 296 if (previous_theme_id != kDefaultThemeID && |
| 297 previous_theme_id != extension->id() && |
| 298 service->GetInstalledExtension(previous_theme_id)) { |
| 299 // Do not disable the previous theme if it is already uninstalled. Sending |
| 300 // NOTIFICATION_BROWSER_THEME_CHANGED causes the previous theme to be |
| 301 // uninstalled when the notification causes the remaining infobar to close |
| 302 // and does not open any new infobars. See crbug.com/468280. |
| 303 |
| 304 // Disable the old theme. |
| 305 service->DisableExtension(previous_theme_id, |
| 306 extensions::Extension::DISABLE_USER_ACTION); |
| 307 } |
| 288 } | 308 } |
| 289 | 309 |
| 290 void ThemeService::UseDefaultTheme() { | 310 void ThemeService::UseDefaultTheme() { |
| 291 if (ready_) | 311 if (ready_) |
| 292 base::RecordAction(UserMetricsAction("Themes_Reset")); | 312 base::RecordAction(UserMetricsAction("Themes_Reset")); |
| 293 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) | 313 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) |
| 294 if (IsSupervisedUser()) { | 314 if (IsSupervisedUser()) { |
| 295 SetSupervisedUserTheme(); | 315 SetSupervisedUserTheme(); |
| 296 return; | 316 return; |
| 297 } | 317 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 322 return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); | 342 return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); |
| 323 } | 343 } |
| 324 | 344 |
| 325 void ThemeService::OnInfobarDisplayed() { | 345 void ThemeService::OnInfobarDisplayed() { |
| 326 number_of_infobars_++; | 346 number_of_infobars_++; |
| 327 } | 347 } |
| 328 | 348 |
| 329 void ThemeService::OnInfobarDestroyed() { | 349 void ThemeService::OnInfobarDestroyed() { |
| 330 number_of_infobars_--; | 350 number_of_infobars_--; |
| 331 | 351 |
| 332 if (number_of_infobars_ == 0 && | 352 if (number_of_infobars_ == 0) |
| 333 !build_extension_task_tracker_.HasTrackedTasks()) { | |
| 334 RemoveUnusedThemes(false); | 353 RemoveUnusedThemes(false); |
| 335 } | |
| 336 } | 354 } |
| 337 | 355 |
| 338 void ThemeService::RemoveUnusedThemes(bool ignore_infobars) { | 356 void ThemeService::RemoveUnusedThemes(bool ignore_infobars) { |
| 339 // We do not want to garbage collect themes on startup (|ready_| is false). | 357 // We do not want to garbage collect themes on startup (|ready_| is false). |
| 340 // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|. | 358 // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|. |
| 341 if (!profile_ || !ready_) | 359 if (!profile_ || !ready_) |
| 342 return; | 360 return; |
| 343 if (!ignore_infobars && number_of_infobars_ != 0) | 361 if (!ignore_infobars && number_of_infobars_ != 0) |
| 344 return; | 362 return; |
| 345 | 363 |
| 346 ExtensionService* service = | 364 ExtensionService* service = |
| 347 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 365 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 348 if (!service) | 366 if (!service) |
| 349 return; | 367 return; |
| 350 | 368 |
| 351 std::string current_theme = GetThemeID(); | 369 std::string current_theme = GetThemeID(); |
| 352 std::vector<std::string> remove_list; | 370 std::vector<std::string> remove_list; |
| 353 std::unique_ptr<const extensions::ExtensionSet> extensions( | 371 std::unique_ptr<const extensions::ExtensionSet> extensions( |
| 354 extensions::ExtensionRegistry::Get(profile_) | 372 extensions::ExtensionRegistry::Get(profile_) |
| 355 ->GenerateInstalledExtensionsSet()); | 373 ->GenerateInstalledExtensionsSet()); |
| 356 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); | 374 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); |
| 357 for (extensions::ExtensionSet::const_iterator it = extensions->begin(); | 375 for (extensions::ExtensionSet::const_iterator it = extensions->begin(); |
| 358 it != extensions->end(); ++it) { | 376 it != extensions->end(); ++it) { |
| 359 const extensions::Extension* extension = it->get(); | 377 const extensions::Extension* extension = it->get(); |
| 360 if (extension->is_theme() && extension->id() != current_theme && | 378 if (extension->is_theme() && |
| 361 extension->id() != building_extension_id_) { | 379 extension->id() != current_theme) { |
| 362 // Only uninstall themes which are not disabled or are disabled with | 380 // Only uninstall themes which are not disabled or are disabled with |
| 363 // reason DISABLE_USER_ACTION. We cannot blanket uninstall all disabled | 381 // reason DISABLE_USER_ACTION. We cannot blanket uninstall all disabled |
| 364 // themes because externally installed themes are initially disabled. | 382 // themes because externally installed themes are initially disabled. |
| 365 int disable_reason = prefs->GetDisableReasons(extension->id()); | 383 int disable_reason = prefs->GetDisableReasons(extension->id()); |
| 366 if (!prefs->IsExtensionDisabled(extension->id()) || | 384 if (!prefs->IsExtensionDisabled(extension->id()) || |
| 367 disable_reason == Extension::DISABLE_USER_ACTION) { | 385 disable_reason == Extension::DISABLE_USER_ACTION) { |
| 368 remove_list.push_back((*it)->id()); | 386 remove_list.push_back((*it)->id()); |
| 369 } | 387 } |
| 370 } | 388 } |
| 371 } | 389 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 else | 571 else |
| 554 UseDefaultTheme(); | 572 UseDefaultTheme(); |
| 555 set_ready(); | 573 set_ready(); |
| 556 return; | 574 return; |
| 557 } | 575 } |
| 558 | 576 |
| 559 bool loaded_pack = false; | 577 bool loaded_pack = false; |
| 560 | 578 |
| 561 // If we don't have a file pack, we're updating from an old version. | 579 // If we don't have a file pack, we're updating from an old version. |
| 562 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); | 580 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); |
| 563 if (!path.empty()) { | 581 if (path != base::FilePath()) { |
| 564 path = path.Append(chrome::kThemePackFilename); | 582 path = path.Append(chrome::kThemePackFilename); |
| 565 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); | 583 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); |
| 566 if (theme_supplier_) | 584 if (theme_supplier_) |
| 567 loaded_pack = true; | 585 loaded_pack = true; |
| 568 } | 586 } |
| 569 | 587 |
| 570 if (loaded_pack) { | 588 if (loaded_pack) { |
| 571 base::RecordAction(UserMetricsAction("Themes.Loaded")); | 589 base::RecordAction(UserMetricsAction("Themes.Loaded")); |
| 572 set_ready(); | 590 set_ready(); |
| 573 } | 591 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 for (int delta = lighten ? 64 : -64; delta != 0; delta /= 2) { | 678 for (int delta = lighten ? 64 : -64; delta != 0; delta /= 2) { |
| 661 const double luminance = color_utils::GetRelativeLuminance( | 679 const double luminance = color_utils::GetRelativeLuminance( |
| 662 color_utils::AlphaBlend(separator_color, frame_color, alpha)); | 680 color_utils::AlphaBlend(separator_color, frame_color, alpha)); |
| 663 if (luminance == target_luminance) | 681 if (luminance == target_luminance) |
| 664 break; | 682 break; |
| 665 alpha += (luminance < target_luminance) ? -delta : delta; | 683 alpha += (luminance < target_luminance) ? -delta : delta; |
| 666 } | 684 } |
| 667 return SkColorSetA(separator_color, alpha); | 685 return SkColorSetA(separator_color, alpha); |
| 668 } | 686 } |
| 669 | 687 |
| 670 void ThemeService::DoSetTheme(const Extension* extension, | |
| 671 bool suppress_infobar) { | |
| 672 DCHECK(extension->is_theme()); | |
| 673 DCHECK(extensions::ExtensionSystem::Get(profile_) | |
| 674 ->extension_service() | |
| 675 ->IsExtensionEnabled(extension->id())); | |
| 676 BuildFromExtension(extension, suppress_infobar); | |
| 677 } | |
| 678 | |
| 679 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const { | 688 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const { |
| 680 gfx::Image image = GetImageNamed(id, incognito); | 689 gfx::Image image = GetImageNamed(id, incognito); |
| 681 if (image.IsEmpty()) | 690 if (image.IsEmpty()) |
| 682 return nullptr; | 691 return nullptr; |
| 683 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns | 692 // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns |
| 684 // its images const. GetImageSkiaNamed() also should but has many callsites. | 693 // its images const. GetImageSkiaNamed() also should but has many callsites. |
| 685 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); | 694 return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); |
| 686 } | 695 } |
| 687 | 696 |
| 688 SkColor ThemeService::GetColor(int id, bool incognito) const { | 697 SkColor ThemeService::GetColor(int id, bool incognito) const { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 778 |
| 770 return image; | 779 return image; |
| 771 } | 780 } |
| 772 | 781 |
| 773 void ThemeService::OnExtensionServiceReady() { | 782 void ThemeService::OnExtensionServiceReady() { |
| 774 if (!ready_) { | 783 if (!ready_) { |
| 775 // If the ThemeService is not ready yet, the custom theme data pack needs to | 784 // If the ThemeService is not ready yet, the custom theme data pack needs to |
| 776 // be recreated from the extension. | 785 // be recreated from the extension. |
| 777 MigrateTheme(); | 786 MigrateTheme(); |
| 778 set_ready(); | 787 set_ready(); |
| 788 |
| 789 // Send notification in case anyone requested data and cached it when the |
| 790 // theme service was not ready yet. |
| 791 NotifyThemeChanged(); |
| 779 } | 792 } |
| 780 | 793 |
| 781 #if BUILDFLAG(ENABLE_EXTENSIONS) | 794 #if BUILDFLAG(ENABLE_EXTENSIONS) |
| 782 theme_observer_.reset(new ThemeObserver(this)); | 795 theme_observer_.reset(new ThemeObserver(this)); |
| 783 #endif | 796 #endif |
| 784 | 797 |
| 785 registrar_.Add(this, | 798 registrar_.Add(this, |
| 786 extensions::NOTIFICATION_EXTENSION_ENABLED, | 799 extensions::NOTIFICATION_EXTENSION_ENABLED, |
| 787 content::Source<Profile>(profile_)); | 800 content::Source<Profile>(profile_)); |
| 788 | 801 |
| 789 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 802 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 790 FROM_HERE, base::Bind(&ThemeService::RemoveUnusedThemes, | 803 FROM_HERE, base::Bind(&ThemeService::RemoveUnusedThemes, |
| 791 weak_ptr_factory_.GetWeakPtr(), false), | 804 weak_ptr_factory_.GetWeakPtr(), false), |
| 792 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); | 805 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); |
| 793 } | 806 } |
| 794 | 807 |
| 795 void ThemeService::MigrateTheme() { | 808 void ThemeService::MigrateTheme() { |
| 809 // TODO(erg): We need to pop up a dialog informing the user that their |
| 810 // theme is being migrated. |
| 796 ExtensionService* service = | 811 ExtensionService* service = |
| 797 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 812 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 798 const Extension* extension = | 813 const Extension* extension = |
| 799 service ? service->GetExtensionById(GetThemeID(), false) : nullptr; | 814 service ? service->GetExtensionById(GetThemeID(), false) : nullptr; |
| 800 if (extension) { | 815 if (extension) { |
| 801 DLOG(ERROR) << "Migrating theme"; | 816 DLOG(ERROR) << "Migrating theme"; |
| 802 // Theme migration is done on the UI thread. Blocking the UI from appearing | 817 BuildFromExtension(extension); |
| 803 // until it's ready is deemed better than showing a blip of the default | |
| 804 // theme. | |
| 805 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); | |
| 806 BrowserThemePack::BuildFromExtension(extension, pack); | |
| 807 OnThemeBuiltFromExtension(extension->id(), pack, true); | |
| 808 base::RecordAction(UserMetricsAction("Themes.Migrated")); | 818 base::RecordAction(UserMetricsAction("Themes.Migrated")); |
| 809 } else { | 819 } else { |
| 810 DLOG(ERROR) << "Theme is mysteriously gone."; | 820 DLOG(ERROR) << "Theme is mysteriously gone."; |
| 811 ClearAllThemeData(); | 821 ClearAllThemeData(); |
| 812 base::RecordAction(UserMetricsAction("Themes.Gone")); | 822 base::RecordAction(UserMetricsAction("Themes.Gone")); |
| 813 } | 823 } |
| 814 } | 824 } |
| 815 | 825 |
| 816 void ThemeService::SwapThemeSupplier( | 826 void ThemeService::SwapThemeSupplier( |
| 817 scoped_refptr<CustomThemeSupplier> theme_supplier) { | 827 scoped_refptr<CustomThemeSupplier> theme_supplier) { |
| 818 if (theme_supplier_) | 828 if (theme_supplier_) |
| 819 theme_supplier_->StopUsingTheme(); | 829 theme_supplier_->StopUsingTheme(); |
| 820 theme_supplier_ = theme_supplier; | 830 theme_supplier_ = theme_supplier; |
| 821 if (theme_supplier_) | 831 if (theme_supplier_) |
| 822 theme_supplier_->StartUsingTheme(); | 832 theme_supplier_->StartUsingTheme(); |
| 823 } | 833 } |
| 824 | 834 |
| 825 void ThemeService::SavePackName(const base::FilePath& pack_path) { | 835 void ThemeService::SavePackName(const base::FilePath& pack_path) { |
| 826 profile_->GetPrefs()->SetFilePath( | 836 profile_->GetPrefs()->SetFilePath( |
| 827 prefs::kCurrentThemePackFilename, pack_path); | 837 prefs::kCurrentThemePackFilename, pack_path); |
| 828 } | 838 } |
| 829 | 839 |
| 830 void ThemeService::SaveThemeID(const std::string& id) { | 840 void ThemeService::SaveThemeID(const std::string& id) { |
| 831 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); | 841 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); |
| 832 } | 842 } |
| 833 | 843 |
| 834 void ThemeService::BuildFromExtension(const Extension* extension, | 844 void ThemeService::BuildFromExtension(const Extension* extension) { |
| 835 bool suppress_infobar) { | 845 scoped_refptr<BrowserThemePack> pack( |
| 836 build_extension_task_tracker_.TryCancelAll(); | 846 BrowserThemePack::BuildFromExtension(extension)); |
| 837 building_extension_id_ = extension->id(); | 847 if (!pack.get()) { |
| 838 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); | |
| 839 auto task_runner = base::CreateTaskRunnerWithTraits( | |
| 840 {base::MayBlock(), base::TaskPriority::USER_BLOCKING}); | |
| 841 build_extension_task_tracker_.PostTaskAndReply( | |
| 842 task_runner.get(), FROM_HERE, | |
| 843 base::Bind(&BrowserThemePack::BuildFromExtension, extension, pack), | |
| 844 base::Bind(&ThemeService::OnThemeBuiltFromExtension, | |
| 845 weak_ptr_factory_.GetWeakPtr(), extension->id(), pack, | |
| 846 suppress_infobar)); | |
| 847 } | |
| 848 | |
| 849 void ThemeService::OnThemeBuiltFromExtension( | |
| 850 const extensions::ExtensionId& extension_id, | |
| 851 scoped_refptr<BrowserThemePack> pack, | |
| 852 bool suppress_infobar) { | |
| 853 if (!pack->is_valid()) { | |
| 854 // TODO(erg): We've failed to install the theme; perhaps we should tell the | 848 // TODO(erg): We've failed to install the theme; perhaps we should tell the |
| 855 // user? http://crbug.com/34780 | 849 // user? http://crbug.com/34780 |
| 856 LOG(ERROR) << "Could not load theme."; | 850 LOG(ERROR) << "Could not load theme."; |
| 857 return; | 851 return; |
| 858 } | 852 } |
| 859 | 853 |
| 860 ExtensionService* service = | 854 ExtensionService* service = |
| 861 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 855 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 862 if (!service) | 856 if (!service) |
| 863 return; | 857 return; |
| 864 const Extension* extension = extensions::ExtensionRegistry::Get(profile_) | |
| 865 ->enabled_extensions() | |
| 866 .GetByID(extension_id); | |
| 867 if (!extension) | |
| 868 return; | |
| 869 | 858 |
| 870 // Write the packed file to disk. | 859 // Write the packed file to disk. |
| 871 service->GetFileTaskRunner()->PostTask( | 860 service->GetFileTaskRunner()->PostTask( |
| 872 FROM_HERE, base::Bind(&WritePackToDiskCallback, base::RetainedRef(pack), | 861 FROM_HERE, base::Bind(&WritePackToDiskCallback, base::RetainedRef(pack), |
| 873 extension->path())); | 862 extension->path())); |
| 874 | 863 |
| 875 const std::string previous_theme_id = GetThemeID(); | |
| 876 const bool previous_using_system_theme = UsingSystemTheme(); | |
| 877 | |
| 878 // Save only the extension path. The packed file will be loaded via | 864 // Save only the extension path. The packed file will be loaded via |
| 879 // LoadThemePrefs(). | 865 // LoadThemePrefs(). |
| 880 SavePackName(extension->path()); | 866 SavePackName(extension->path()); |
| 881 SwapThemeSupplier(pack); | 867 SwapThemeSupplier(pack); |
| 882 | |
| 883 // Clear our image cache. | |
| 884 FreePlatformCaches(); | |
| 885 SaveThemeID(extension->id()); | |
| 886 NotifyThemeChanged(); | |
| 887 | |
| 888 // Same old theme, but the theme has changed (migrated) or auto-updated. | |
| 889 if (previous_theme_id == extension->id()) | |
| 890 return; | |
| 891 | |
| 892 base::RecordAction(UserMetricsAction("Themes_Installed")); | |
| 893 | |
| 894 bool can_revert_theme = previous_theme_id == kDefaultThemeID; | |
| 895 if (previous_theme_id != kDefaultThemeID && | |
| 896 service->GetInstalledExtension(previous_theme_id)) { | |
| 897 // Do not disable the previous theme if it is already uninstalled. Sending | |
| 898 // NOTIFICATION_BROWSER_THEME_CHANGED causes the previous theme to be | |
| 899 // uninstalled when the notification causes the remaining infobar to close | |
| 900 // and does not open any new infobars. See crbug.com/468280. | |
| 901 | |
| 902 // Disable the old theme. | |
| 903 service->DisableExtension(previous_theme_id, | |
| 904 extensions::Extension::DISABLE_USER_ACTION); | |
| 905 | |
| 906 can_revert_theme = true; | |
| 907 } | |
| 908 | |
| 909 // Offer to revert to the old theme. | |
| 910 if (can_revert_theme && !suppress_infobar) { | |
| 911 ThemeInstalledInfoBarDelegate::Create( | |
| 912 extension, profile_, previous_theme_id, previous_using_system_theme); | |
| 913 } | |
| 914 building_extension_id_.clear(); | |
| 915 } | 868 } |
| 916 | 869 |
| 917 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) | 870 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) |
| 918 bool ThemeService::IsSupervisedUser() const { | 871 bool ThemeService::IsSupervisedUser() const { |
| 919 return profile_->IsSupervised(); | 872 return profile_->IsSupervised(); |
| 920 } | 873 } |
| 921 | 874 |
| 922 void ThemeService::SetSupervisedUserTheme() { | 875 void ThemeService::SetSupervisedUserTheme() { |
| 923 SetCustomDefaultTheme(new SupervisedUserTheme); | 876 SetCustomDefaultTheme(new SupervisedUserTheme); |
| 924 } | 877 } |
| 925 #endif | 878 #endif |
| OLD | NEW |