Chromium Code Reviews| Index: chrome/browser/chromeos/customization_document.cc |
| diff --git a/chrome/browser/chromeos/customization_document.cc b/chrome/browser/chromeos/customization_document.cc |
| index 85a93df3d4bf478e5a660b783fdfba02a212b075..5125c1ca1413d4dfffbd45e5c02d52d5d2dea12c 100644 |
| --- a/chrome/browser/chromeos/customization_document.cc |
| +++ b/chrome/browser/chromeos/customization_document.cc |
| @@ -14,6 +14,7 @@ |
| #include "base/logging.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/path_service.h" |
| #include "base/prefs/pref_registry_simple.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/strings/string_split.h" |
| @@ -22,7 +23,9 @@ |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/chromeos/customization_wallpaper_downloader.h" |
| #include "chrome/browser/chromeos/extensions/default_app_order.h" |
| +#include "chrome/browser/chromeos/login/wallpaper_manager.h" |
| #include "chrome/browser/chromeos/login/wizard_controller.h" |
| #include "chrome/browser/chromeos/net/delay_network_call.h" |
| #include "chrome/browser/extensions/external_loader.h" |
| @@ -30,7 +33,9 @@ |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/app_list/app_list_syncable_service.h" |
| #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" |
| +#include "chrome/common/chrome_paths.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| +#include "chrome/common/pref_names.h" |
| #include "chromeos/network/network_state.h" |
| #include "chromeos/network/network_state_handler.h" |
| #include "chromeos/system/statistics_provider.h" |
| @@ -68,6 +73,14 @@ const char kAcceptedManifestVersion[] = "1.0"; |
| const char kStartupCustomizationManifestPath[] = |
| "/opt/oem/etc/startup_manifest.json"; |
| +// This is subdirectory relative to PathService(DIR_CHROMEOS_CUSTOM_WALLPAPERS), |
| +// where downloaded (and resized) wallpaper is stored. |
| +const char kCustomizationDefaultWallpaperDir[] = "customization"; |
| + |
| +// The original downloaded image file is stored under this name. |
| +const char kCustomizationDefaultWallpaperDownloadedFile[] = |
| + "default_downloaded_wallpaper.bin"; |
| + |
| // Name of local state option that tracks if services customization has been |
| // applied. |
| const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; |
| @@ -130,6 +143,12 @@ std::string GetLocaleSpecificStringImpl( |
| return std::string(); |
| } |
| +void CheckWallpaperCacheExists(const base::FilePath& path, bool* exists) { |
| + DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| + DCHECK(exists); |
| + *exists = base::PathExists(path); |
| +} |
| + |
| } // anonymous namespace |
| // Template URL where to fetch OEM services customization manifest from. |
| @@ -337,20 +356,60 @@ std::string StartupCustomizationDocument::GetEULAPage( |
| // ServicesCustomizationDocument implementation. ------------------------------- |
| +class ServicesCustomizationDocument::ApplyingTask { |
| + public: |
| + // Registers in ServicesCustomizationDocument; |
| + ApplyingTask(ServicesCustomizationDocument* document); |
| + |
| + // Do not automatically deregister as we might be called on invalid thread. |
| + ~ApplyingTask(); |
| + |
| + // Mark task finished and check for customization applied. |
| + void Finished(bool success); |
| + |
| + private: |
| + ServicesCustomizationDocument* document_; |
| + bool engaged_; |
|
Nikita (slow)
2014/04/17 05:23:34
nit: Add comment for engaged_.
Alexander Alekseev
2014/04/17 14:34:39
Done.
|
| +}; |
| + |
| +ServicesCustomizationDocument::ApplyingTask::ApplyingTask( |
| + ServicesCustomizationDocument* document) |
| + : document_(document), engaged_(true) { |
| + document->ApplyingTaskStarted(); |
| +} |
| + |
| +ServicesCustomizationDocument::ApplyingTask::~ApplyingTask() { |
| + DCHECK(!engaged_); |
| +} |
| + |
| +void ServicesCustomizationDocument::ApplyingTask::Finished(bool success) { |
| + DCHECK(engaged_); |
| + if (engaged_) { |
| + engaged_ = false; |
| + document_->ApplyingTaskFinished(success); |
| + } |
| +} |
| + |
| ServicesCustomizationDocument::ServicesCustomizationDocument() |
| : CustomizationDocument(kAcceptedManifestVersion), |
| num_retries_(0), |
| fetch_started_(false), |
| - network_delay_(base::TimeDelta::FromMilliseconds( |
| - kDefaultNetworkRetryDelayMS)), |
| + network_delay_( |
| + base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), |
| + apply_tasks_started_(0), |
| + apply_tasks_finished_(0), |
| + apply_tasks_success_(0), |
| weak_ptr_factory_(this) { |
| } |
| ServicesCustomizationDocument::ServicesCustomizationDocument( |
| const std::string& manifest) |
| : CustomizationDocument(kAcceptedManifestVersion), |
| - network_delay_(base::TimeDelta::FromMilliseconds( |
| - kDefaultNetworkRetryDelayMS)), |
| + network_delay_( |
| + base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), |
| + apply_tasks_started_(0), |
| + apply_tasks_finished_(0), |
| + apply_tasks_success_(0), |
| weak_ptr_factory_(this) { |
| LoadManifestFromString(manifest); |
| } |
| @@ -370,6 +429,8 @@ ServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { |
| void ServicesCustomizationDocument::RegisterPrefs( |
| PrefRegistrySimple* registry) { |
| registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); |
| + registry->RegisterStringPref(prefs::kCustomizationDefaultWallpaperURL, |
| + std::string()); |
| } |
| // static |
| @@ -392,6 +453,45 @@ void ServicesCustomizationDocument::SetApplied(bool val) { |
| prefs->SetBoolean(kServicesCustomizationAppliedPref, val); |
| } |
| +// static |
| +base::FilePath ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir() { |
| + base::FilePath custom_wallpaper_dir; |
| + if (!PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS, |
| + &custom_wallpaper_dir)) { |
| + LOG(DFATAL) << "Unable to get custom wallpaper dir."; |
| + return base::FilePath(); |
| + } |
| + return custom_wallpaper_dir.Append(kCustomizationDefaultWallpaperDir); |
| +} |
| + |
| +// static |
| +base::FilePath |
| +ServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName() { |
| + const base::FilePath dir = GetCustomizedWallpaperCacheDir(); |
| + if (dir.empty()) { |
| + NOTREACHED(); |
| + return dir; |
| + } |
| + return dir.Append(kCustomizationDefaultWallpaperDownloadedFile); |
| +} |
| + |
| +void ServicesCustomizationDocument::EnsureCustomizationApplied() { |
| + if (WasOOBECustomizationApplied()) |
| + return; |
| + |
| + // When customization manifest is fetched, applying will start automatically. |
| + if (IsReady()) |
| + return; |
| + |
| + StartFetching(); |
| +} |
| + |
| +base::Closure |
| +ServicesCustomizationDocument::EnsureCustomizationAppliedClosure() { |
| + return base::Bind(&ServicesCustomizationDocument::EnsureCustomizationApplied, |
| + weak_ptr_factory_.GetWeakPtr()); |
| +} |
| + |
| void ServicesCustomizationDocument::StartFetching() { |
| if (IsReady() || fetch_started_) |
| return; |
| @@ -479,7 +579,7 @@ bool ServicesCustomizationDocument::LoadManifestFromString( |
| } |
| void ServicesCustomizationDocument::OnManifestLoaded() { |
| - if (!ServicesCustomizationDocument::WasOOBECustomizationApplied()) |
| + if (!WasOOBECustomizationApplied()) |
| ApplyOOBECustomization(); |
| scoped_ptr<base::DictionaryValue> prefs = |
| @@ -531,9 +631,11 @@ void ServicesCustomizationDocument::OnURLFetchComplete( |
| } |
| bool ServicesCustomizationDocument::ApplyOOBECustomization() { |
| - // TODO(dpolukhin): apply default wallpaper, crbug.com/348136. |
| - SetApplied(true); |
| - return true; |
| + if (apply_tasks_started_) |
| + return false; |
| + |
| + CheckAndApplyWallpaper(); |
| + return false; |
| } |
| GURL ServicesCustomizationDocument::GetDefaultWallpaperUrl() const { |
| @@ -675,4 +777,145 @@ void ServicesCustomizationDocument::ShutdownForTesting() { |
| g_test_services_customization_document = NULL; |
| } |
| +void ServicesCustomizationDocument::StartOEMWallpaperDownload( |
| + const GURL& wallpaper_url, |
| + scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| + DCHECK(wallpaper_url.is_valid()); |
| + |
| + const base::FilePath dir = GetCustomizedWallpaperCacheDir(); |
| + const base::FilePath file = GetCustomizedWallpaperDownloadedFileName(); |
| + if (dir.empty() || file.empty()) { |
| + NOTREACHED(); |
| + applying->Finished(false); |
| + return; |
| + } |
| + |
| + wallpaper_downloader_.reset(new CustomizationWallpaperDownloader( |
| + g_browser_process->system_request_context(), |
| + wallpaper_url, |
| + dir, |
| + file, |
| + base::Bind(&ServicesCustomizationDocument::OnOEMWallpaperDownloaded, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + base::Passed(applying.Pass())))); |
| + |
| + wallpaper_downloader_->Start(); |
| +} |
| + |
| +void ServicesCustomizationDocument::CheckAndApplyWallpaper() { |
| + if (wallpaper_downloader_.get()) { |
| + VLOG(1) << "CheckAndApplyWallpaper(): download has already started."; |
| + return; |
| + } |
| + scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying( |
| + new ServicesCustomizationDocument::ApplyingTask(this)); |
| + |
| + GURL wallpaper_url = GetDefaultWallpaperUrl(); |
| + |
| + // Should fail if this ever happens in tests. |
| + DCHECK(wallpaper_url.is_valid()); |
| + if (!wallpaper_url.is_valid()) { |
| + if (!wallpaper_url.is_empty()) { |
| + LOG(WARNING) << "Invalid Customized Wallpaper URL '" |
| + << wallpaper_url.spec() << "'."; |
| + } |
| + applying->Finished(false); |
| + return; |
| + } |
| + |
| + scoped_ptr<bool> exists(new bool(false)); |
| + |
| + base::Closure check_file_exists = |
| + base::Bind(&CheckWallpaperCacheExists, |
| + GetCustomizedWallpaperDownloadedFileName(), |
| + base::Unretained(exists.get())); |
| + base::Closure on_checked_closure = |
| + base::Bind(&ServicesCustomizationDocument::OnCheckedWallpaperCacheExists, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + base::Passed(exists.Pass()), |
| + base::Passed(applying.Pass())); |
| + if (!content::BrowserThread::PostBlockingPoolTaskAndReply( |
| + FROM_HERE, check_file_exists, on_checked_closure)) { |
| + LOG(WARNING) << "Failed to start check Wallpaper cache exists."; |
| + } |
| +} |
| + |
| +void ServicesCustomizationDocument::OnCheckedWallpaperCacheExists( |
| + scoped_ptr<bool> exists, |
| + scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + DCHECK(exists); |
| + DCHECK(applying); |
| + |
| + ApplyWallpaper(*exists, applying.Pass()); |
| +} |
| + |
| +void ServicesCustomizationDocument::ApplyWallpaper( |
| + bool default_wallpaper_file_exists, |
| + scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| + GURL wallpaper_url = GetDefaultWallpaperUrl(); |
| + DCHECK(wallpaper_url.is_valid()); |
| + |
| + PrefService* pref_service = g_browser_process->local_state(); |
| + |
| + std::string current_url = |
| + pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| + if (current_url != wallpaper_url.spec()) { |
| + VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " |
| + << "Wallpaper URL in customization document '" |
| + << wallpaper_url.spec() << "' differs from current '" << current_url |
| + << "'." |
| + << (GURL(current_url).is_valid() && default_wallpaper_file_exists |
| + ? " Ignored." |
| + : " Will refetch."); |
| + } |
| + // Never update system-wide wallpaper (i.e. do not check |
| + // current_url == wallpaper_url.spec() ) |
| + if (GURL(current_url).is_valid() && default_wallpaper_file_exists) { |
| + VLOG(1) |
| + << "ServicesCustomizationDocument::ApplyWallpaper() : reuse existing"; |
| + OnOEMWallpaperDownloaded(applying.Pass(), true, GURL(current_url)); |
| + } else { |
| + VLOG(1) |
| + << "ServicesCustomizationDocument::ApplyWallpaper() : start download"; |
| + StartOEMWallpaperDownload(wallpaper_url, applying.Pass()); |
| + } |
| +} |
| + |
| +void ServicesCustomizationDocument::OnOEMWallpaperDownloaded( |
| + scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying, |
| + bool success, |
| + const GURL& wallpaper_url) { |
| + if (success) { |
| + DCHECK(wallpaper_url.is_valid()); |
| + |
| + VLOG(1) << "Setting default wallpaper to '" |
| + << GetCustomizedWallpaperDownloadedFileName().value() << "' ('" |
| + << wallpaper_url.spec() << "')"; |
| + WallpaperManager::Get()->SetCustomizedDefaultWallpaper( |
| + wallpaper_url, |
| + GetCustomizedWallpaperDownloadedFileName(), |
| + GetCustomizedWallpaperCacheDir()); |
| + } |
| + wallpaper_downloader_.reset(); |
| + applying->Finished(success); |
| +} |
| + |
| +void ServicesCustomizationDocument::ApplyingTaskStarted() { |
| + ++apply_tasks_started_; |
| +} |
| + |
| +void ServicesCustomizationDocument::ApplyingTaskFinished(bool success) { |
| + DCHECK(apply_tasks_started_ > apply_tasks_finished_); |
| + ++apply_tasks_finished_; |
| + |
| + apply_tasks_success_ += success; |
| + |
| + if (apply_tasks_started_ != apply_tasks_finished_) |
| + return; |
| + |
| + if (apply_tasks_success_ == apply_tasks_finished_) |
| + SetApplied(true); |
| +} |
| + |
| } // namespace chromeos |