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/chromeos/customization_document.h" | 5 #include "chrome/browser/chromeos/customization_document.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" | 
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" | 
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" | 
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" | 
| 14 #include "base/logging.h" | 14 #include "base/logging.h" | 
| 15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" | 
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" | 
| 17 #include "base/path_service.h" | |
| 17 #include "base/prefs/pref_registry_simple.h" | 18 #include "base/prefs/pref_registry_simple.h" | 
| 18 #include "base/prefs/pref_service.h" | 19 #include "base/prefs/pref_service.h" | 
| 19 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" | 
| 20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" | 
| 21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" | 
| 22 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" | 
| 23 #include "base/time/time.h" | 24 #include "base/time/time.h" | 
| 24 #include "chrome/browser/browser_process.h" | 25 #include "chrome/browser/browser_process.h" | 
| 26 #include "chrome/browser/chromeos/customization_wallpaper_downloader.h" | |
| 25 #include "chrome/browser/chromeos/extensions/default_app_order.h" | 27 #include "chrome/browser/chromeos/extensions/default_app_order.h" | 
| 28 #include "chrome/browser/chromeos/login/wallpaper_manager.h" | |
| 26 #include "chrome/browser/chromeos/login/wizard_controller.h" | 29 #include "chrome/browser/chromeos/login/wizard_controller.h" | 
| 27 #include "chrome/browser/chromeos/net/delay_network_call.h" | 30 #include "chrome/browser/chromeos/net/delay_network_call.h" | 
| 28 #include "chrome/browser/extensions/external_loader.h" | 31 #include "chrome/browser/extensions/external_loader.h" | 
| 29 #include "chrome/browser/extensions/external_provider_impl.h" | 32 #include "chrome/browser/extensions/external_provider_impl.h" | 
| 30 #include "chrome/browser/profiles/profile.h" | 33 #include "chrome/browser/profiles/profile.h" | 
| 31 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" | 34 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" | 
| 32 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" | 35 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" | 
| 36 #include "chrome/common/chrome_paths.h" | |
| 33 #include "chrome/common/extensions/extension_constants.h" | 37 #include "chrome/common/extensions/extension_constants.h" | 
| 38 #include "chrome/common/pref_names.h" | |
| 34 #include "chromeos/network/network_state.h" | 39 #include "chromeos/network/network_state.h" | 
| 35 #include "chromeos/network/network_state_handler.h" | 40 #include "chromeos/network/network_state_handler.h" | 
| 36 #include "chromeos/system/statistics_provider.h" | 41 #include "chromeos/system/statistics_provider.h" | 
| 37 #include "components/user_prefs/pref_registry_syncable.h" | 42 #include "components/user_prefs/pref_registry_syncable.h" | 
| 38 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" | 
| 39 #include "net/base/load_flags.h" | 44 #include "net/base/load_flags.h" | 
| 40 #include "net/http/http_response_headers.h" | 45 #include "net/http/http_response_headers.h" | 
| 41 #include "net/http/http_status_code.h" | 46 #include "net/http/http_status_code.h" | 
| 42 #include "net/url_request/url_fetcher.h" | 47 #include "net/url_request/url_fetcher.h" | 
| 43 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 61 const char kDefaultAppsAttr[] = "default_apps"; | 66 const char kDefaultAppsAttr[] = "default_apps"; | 
| 62 const char kLocalizedContent[] = "localized_content"; | 67 const char kLocalizedContent[] = "localized_content"; | 
| 63 const char kDefaultAppsFolderName[] = "default_apps_folder_name"; | 68 const char kDefaultAppsFolderName[] = "default_apps_folder_name"; | 
| 64 | 69 | 
| 65 const char kAcceptedManifestVersion[] = "1.0"; | 70 const char kAcceptedManifestVersion[] = "1.0"; | 
| 66 | 71 | 
| 67 // Path to OEM partner startup customization manifest. | 72 // Path to OEM partner startup customization manifest. | 
| 68 const char kStartupCustomizationManifestPath[] = | 73 const char kStartupCustomizationManifestPath[] = | 
| 69 "/opt/oem/etc/startup_manifest.json"; | 74 "/opt/oem/etc/startup_manifest.json"; | 
| 70 | 75 | 
| 76 // This is subdirectory relative to PathService(DIR_CHROMEOS_CUSTOM_WALLPAPERS), | |
| 77 // where downloaded (and resized) wallpaper is stored. | |
| 78 const char kCustomizationDefaultWallpaperDir[] = "customization"; | |
| 79 | |
| 80 // The original downloaded image file is stored under this name. | |
| 81 const char kCustomizationDefaultWallpaperDownloadedFile[] = | |
| 82 "default.downloaded"; | |
| 83 | |
| 71 // Name of local state option that tracks if services customization has been | 84 // Name of local state option that tracks if services customization has been | 
| 72 // applied. | 85 // applied. | 
| 73 const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; | 86 const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; | 
| 74 | 87 | 
| 75 // Maximum number of retries to fetch file if network is not available. | 88 // Maximum number of retries to fetch file if network is not available. | 
| 76 const int kMaxFetchRetries = 3; | 89 const int kMaxFetchRetries = 3; | 
| 77 | 90 | 
| 78 // Delay between file fetch retries if network is not available. | 91 // Delay between file fetch retries if network is not available. | 
| 79 const int kRetriesDelayInSec = 2; | 92 const int kRetriesDelayInSec = 2; | 
| 80 | 93 | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 const base::DictionaryValue* default_dictionary = NULL; | 136 const base::DictionaryValue* default_dictionary = NULL; | 
| 124 if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { | 137 if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { | 
| 125 std::string result; | 138 std::string result; | 
| 126 if (default_dictionary->GetString(entry_name, &result)) | 139 if (default_dictionary->GetString(entry_name, &result)) | 
| 127 return result; | 140 return result; | 
| 128 } | 141 } | 
| 129 | 142 | 
| 130 return std::string(); | 143 return std::string(); | 
| 131 } | 144 } | 
| 132 | 145 | 
| 146 void CheckWallpaperCacheExists(const base::FilePath& path, bool* exists) { | |
| 147 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | |
| 148 DCHECK(exists); | |
| 149 *exists = base::PathExists(path); | |
| 150 } | |
| 151 | |
| 133 } // anonymous namespace | 152 } // anonymous namespace | 
| 134 | 153 | 
| 135 // Template URL where to fetch OEM services customization manifest from. | 154 // Template URL where to fetch OEM services customization manifest from. | 
| 136 const char ServicesCustomizationDocument::kManifestUrl[] = | 155 const char ServicesCustomizationDocument::kManifestUrl[] = | 
| 137 "https://ssl.gstatic.com/chrome/chromeos-customization/%s.json"; | 156 "https://ssl.gstatic.com/chrome/chromeos-customization/%s.json"; | 
| 138 | 157 | 
| 139 // A custom extensions::ExternalLoader that the ServicesCustomizationDocument | 158 // A custom extensions::ExternalLoader that the ServicesCustomizationDocument | 
| 140 // creates and uses to publish OEM default apps to the extensions system. | 159 // creates and uses to publish OEM default apps to the extensions system. | 
| 141 class ServicesCustomizationExternalLoader | 160 class ServicesCustomizationExternalLoader | 
| 142 : public extensions::ExternalLoader, | 161 : public extensions::ExternalLoader, | 
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 return g_test_services_customization_document; | 382 return g_test_services_customization_document; | 
| 364 | 383 | 
| 365 return Singleton<ServicesCustomizationDocument, | 384 return Singleton<ServicesCustomizationDocument, | 
| 366 DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); | 385 DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); | 
| 367 } | 386 } | 
| 368 | 387 | 
| 369 // static | 388 // static | 
| 370 void ServicesCustomizationDocument::RegisterPrefs( | 389 void ServicesCustomizationDocument::RegisterPrefs( | 
| 371 PrefRegistrySimple* registry) { | 390 PrefRegistrySimple* registry) { | 
| 372 registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); | 391 registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); | 
| 392 registry->RegisterStringPref(prefs::kCustomizationDefaultWallpaperURL, ""); | |
| 373 } | 393 } | 
| 374 | 394 | 
| 375 // static | 395 // static | 
| 376 void ServicesCustomizationDocument::RegisterProfilePrefs( | 396 void ServicesCustomizationDocument::RegisterProfilePrefs( | 
| 377 user_prefs::PrefRegistrySyncable* registry) { | 397 user_prefs::PrefRegistrySyncable* registry) { | 
| 378 registry->RegisterDictionaryPref( | 398 registry->RegisterDictionaryPref( | 
| 379 kServicesCustomizationKey, | 399 kServicesCustomizationKey, | 
| 380 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 400 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 
| 381 } | 401 } | 
| 382 | 402 | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 LOG(ERROR) << "URL fetch for services customization failed:" | 544 LOG(ERROR) << "URL fetch for services customization failed:" | 
| 525 << " response code = " << source->GetResponseCode() | 545 << " response code = " << source->GetResponseCode() | 
| 526 << " URL = " << source->GetURL().spec(); | 546 << " URL = " << source->GetURL().spec(); | 
| 527 | 547 | 
| 528 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); | 548 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); | 
| 529 } | 549 } | 
| 530 fetch_started_ = false; | 550 fetch_started_ = false; | 
| 531 } | 551 } | 
| 532 | 552 | 
| 533 bool ServicesCustomizationDocument::ApplyOOBECustomization() { | 553 bool ServicesCustomizationDocument::ApplyOOBECustomization() { | 
| 534 // TODO(dpolukhin): apply default wallpaper, crbug.com/348136. | 554 CheckAndApplyWallpaper(); | 
| 535 SetApplied(true); | 555 SetApplied(true); | 
| 536 return true; | 556 return true; | 
| 537 } | 557 } | 
| 538 | 558 | 
| 539 GURL ServicesCustomizationDocument::GetDefaultWallpaperUrl() const { | 559 GURL ServicesCustomizationDocument::GetDefaultWallpaperUrl() const { | 
| 540 if (!IsReady()) | 560 if (!IsReady()) | 
| 541 return GURL(); | 561 return GURL(); | 
| 542 | 562 | 
| 543 std::string url; | 563 std::string url; | 
| 544 root_->GetString(kDefaultWallpaperAttr, &url); | 564 root_->GetString(kDefaultWallpaperAttr, &url); | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 569 } | 589 } | 
| 570 | 590 | 
| 571 std::string ServicesCustomizationDocument::GetOemAppsFolderName( | 591 std::string ServicesCustomizationDocument::GetOemAppsFolderName( | 
| 572 const std::string& locale) const { | 592 const std::string& locale) const { | 
| 573 if (!IsReady()) | 593 if (!IsReady()) | 
| 574 return std::string(); | 594 return std::string(); | 
| 575 | 595 | 
| 576 return GetOemAppsFolderNameImpl(locale, *root_); | 596 return GetOemAppsFolderNameImpl(locale, *root_); | 
| 577 } | 597 } | 
| 578 | 598 | 
| 599 // static | |
| 600 base::FilePath ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir() { | |
| 601 base::FilePath custom_wallpaper_dir; | |
| 602 const bool success = PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS, | |
| 603 &custom_wallpaper_dir); | |
| 604 DCHECK(success); | |
| 605 | |
| 606 if (success) | |
| 607 return custom_wallpaper_dir.Append(kCustomizationDefaultWallpaperDir); | |
| 608 | |
| 609 return custom_wallpaper_dir; | |
| 610 } | |
| 611 | |
| 612 // static | |
| 613 base::FilePath | |
| 614 ServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName() { | |
| 615 const base::FilePath dir = GetCustomizedWallpaperCacheDir(); | |
| 616 if (dir.empty()) | |
| 617 return dir; | |
| 618 return dir.Append(kCustomizationDefaultWallpaperDownloadedFile); | |
| 619 } | |
| 620 | |
| 621 void ServicesCustomizationDocument::DestroyWallpaperDownloader() { | |
| 622 wallpaper_downloader_.reset(); | |
| 623 } | |
| 624 | |
| 579 scoped_ptr<base::DictionaryValue> | 625 scoped_ptr<base::DictionaryValue> | 
| 580 ServicesCustomizationDocument::GetDefaultAppsInProviderFormat( | 626 ServicesCustomizationDocument::GetDefaultAppsInProviderFormat( | 
| 581 const base::DictionaryValue& root) { | 627 const base::DictionaryValue& root) { | 
| 582 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); | 628 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); | 
| 583 const base::ListValue* apps_list = NULL; | 629 const base::ListValue* apps_list = NULL; | 
| 584 if (root.GetList(kDefaultAppsAttr, &apps_list)) { | 630 if (root.GetList(kDefaultAppsAttr, &apps_list)) { | 
| 585 for (size_t i = 0; i < apps_list->GetSize(); ++i) { | 631 for (size_t i = 0; i < apps_list->GetSize(); ++i) { | 
| 586 std::string app_id; | 632 std::string app_id; | 
| 587 if (apps_list->GetString(i, &app_id)) { | 633 if (apps_list->GetString(i, &app_id)) { | 
| 588 base::DictionaryValue* entry = new base::DictionaryValue; | 634 base::DictionaryValue* entry = new base::DictionaryValue; | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 g_test_services_customization_document = new ServicesCustomizationDocument; | 714 g_test_services_customization_document = new ServicesCustomizationDocument; | 
| 669 g_test_services_customization_document->network_delay_ = base::TimeDelta(); | 715 g_test_services_customization_document->network_delay_ = base::TimeDelta(); | 
| 670 } | 716 } | 
| 671 | 717 | 
| 672 // static | 718 // static | 
| 673 void ServicesCustomizationDocument::ShutdownForTesting() { | 719 void ServicesCustomizationDocument::ShutdownForTesting() { | 
| 674 delete g_test_services_customization_document; | 720 delete g_test_services_customization_document; | 
| 675 g_test_services_customization_document = NULL; | 721 g_test_services_customization_document = NULL; | 
| 676 } | 722 } | 
| 677 | 723 | 
| 724 void ServicesCustomizationDocument::StartOEMWallpaperDownload( | |
| 725 const GURL& wallpaper_url) { | |
| 726 DCHECK(wallpaper_url.is_valid()); | |
| 727 | |
| 728 const base::FilePath dir = GetCustomizedWallpaperCacheDir(); | |
| 729 const base::FilePath file = GetCustomizedWallpaperDownloadedFileName(); | |
| 730 if (!dir.empty() && !file.empty()) { | |
| 
 
Daniel Erat
2014/04/14 15:26:15
nit: just do this so the rest of this method doesn
 
Alexander Alekseev
2014/04/15 01:57:16
Done.
 
 | |
| 731 wallpaper_downloader_.reset(new CustomizationWallpaperDownloader( | |
| 732 g_browser_process->system_request_context(), | |
| 733 wallpaper_url, | |
| 734 dir, | |
| 735 file, | |
| 736 base::Bind( | |
| 737 &ServicesCustomizationDocument::OnCustomizedWallpaperDownloaded, | |
| 738 weak_ptr_factory_.GetWeakPtr()))); | |
| 739 | |
| 740 wallpaper_downloader_->Start(); | |
| 741 } | |
| 742 } | |
| 743 | |
| 744 void ServicesCustomizationDocument::CheckAndApplyWallpaper() { | |
| 745 if (wallpaper_downloader_.get()) { | |
| 746 VLOG(1) << "CheckAndApplyWallpaper(): download has already started."; | |
| 747 return; | |
| 748 } | |
| 749 GURL wallpaper_url = GetDefaultWallpaperUrl(); | |
| 750 // Should fail if this ever happens in tests. | |
| 751 DCHECK(wallpaper_url.is_valid() || wallpaper_url.is_empty()); | |
| 
 
Daniel Erat
2014/04/14 15:26:15
do you need these is_empty checks? url/gurl.h says
 
Alexander Alekseev
2014/04/15 01:57:16
Done.
 
 | |
| 752 if (!wallpaper_url.is_valid()) { | |
| 753 if (!wallpaper_url.is_empty()) { | |
| 754 LOG(WARNING) << "Invalid Customized Wallpaper URL."; | |
| 755 } | |
| 756 return; | |
| 757 } | |
| 758 scoped_ptr<bool> exists(new bool(false)); | |
| 759 | |
| 760 base::Closure check_file_exists = | |
| 761 base::Bind(&CheckWallpaperCacheExists, | |
| 762 GetCustomizedWallpaperDownloadedFileName(), | |
| 763 base::Unretained(exists.get())); | |
| 764 base::Closure on_checked_closure = | |
| 765 base::Bind(&ServicesCustomizationDocument::OnCheckedWallpaperCacheExists, | |
| 766 weak_ptr_factory_.GetWeakPtr(), | |
| 767 base::Passed(exists.Pass())); | |
| 768 if (!content::BrowserThread::PostBlockingPoolTaskAndReply( | |
| 769 FROM_HERE, check_file_exists, on_checked_closure)) { | |
| 770 LOG(WARNING) << "Failed to start check Wallpaper cache exists."; | |
| 771 } | |
| 772 } | |
| 773 | |
| 774 void ServicesCustomizationDocument::OnCheckedWallpaperCacheExists( | |
| 775 scoped_ptr<bool> exists) { | |
| 776 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 777 DCHECK(exists.get()); | |
| 778 | |
| 779 ApplyWallpaper(*exists); | |
| 780 } | |
| 781 | |
| 782 void ServicesCustomizationDocument::ApplyWallpaper( | |
| 783 bool default_wallpaper_file_exists) { | |
| 784 GURL wallpaper_url = GetDefaultWallpaperUrl(); | |
| 785 DCHECK(wallpaper_url.is_valid()); | |
| 786 | |
| 787 PrefService* pref_service = g_browser_process->local_state(); | |
| 788 | |
| 789 std::string current_url = | |
| 790 pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); | |
| 791 if (current_url != wallpaper_url.spec()) { | |
| 792 VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " | |
| 793 << "Wallpaper URL in customization document '" | |
| 794 << wallpaper_url.spec() << "' differs from current '" << current_url | |
| 795 << "'." | |
| 796 << (GURL(current_url).is_valid() && default_wallpaper_file_exists | |
| 797 ? " Ignored." | |
| 798 : " Will refetch."); | |
| 799 } | |
| 800 // Never update system-wide wallpaper (i.e. do not check | |
| 801 // current_url == wallpaper_url.spec() ) | |
| 802 if (GURL(current_url).is_valid() && default_wallpaper_file_exists) { | |
| 803 VLOG(1) | |
| 804 << "ServicesCustomizationDocument::ApplyWallpaper() : reuse existing"; | |
| 805 OnCustomizedWallpaperDownloaded(GURL(current_url)); | |
| 806 } else { | |
| 807 VLOG(1) | |
| 808 << "ServicesCustomizationDocument::ApplyWallpaper() : start download"; | |
| 809 StartOEMWallpaperDownload(wallpaper_url); | |
| 810 } | |
| 811 } | |
| 812 | |
| 813 void ServicesCustomizationDocument::OnCustomizedWallpaperDownloaded( | |
| 814 const GURL& wallpaper_url) { | |
| 815 DCHECK(wallpaper_url.is_valid()); | |
| 816 | |
| 817 VLOG(1) << "Setting default wallpaper to '" | |
| 818 << GetCustomizedWallpaperDownloadedFileName().value() << "' ('" | |
| 819 << wallpaper_url.spec() << "')"; | |
| 820 WallpaperManager::Get()->SetCustomizedDefaultWallpaper( | |
| 821 wallpaper_url, | |
| 822 GetCustomizedWallpaperDownloadedFileName(), | |
| 823 GetCustomizedWallpaperCacheDir()); | |
| 824 } | |
| 825 | |
| 678 } // namespace chromeos | 826 } // namespace chromeos | 
| OLD | NEW |