| Index: chrome/browser/chromeos/customization_wallpaper_downloader.cc | 
| diff --git a/chrome/browser/chromeos/customization_wallpaper_downloader.cc b/chrome/browser/chromeos/customization_wallpaper_downloader.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..90ae00c049e27502bce985aeb36adb8aaf3ad298 | 
| --- /dev/null | 
| +++ b/chrome/browser/chromeos/customization_wallpaper_downloader.cc | 
| @@ -0,0 +1,189 @@ | 
| +// Copyright 2014 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "chrome/browser/chromeos/customization_wallpaper_downloader.h" | 
| + | 
| +#include "base/file_util.h" | 
| +#include "chrome/browser/chromeos/customization_document.h" | 
| +#include "content/public/browser/browser_thread.h" | 
| +#include "net/base/load_flags.h" | 
| +#include "net/url_request/url_request_context_getter.h" | 
| +#include "url/gurl.h" | 
| + | 
| +namespace { | 
| +// This is temporary file suffix (for downloading or resizing). | 
| +const char kTemporarySuffix[] = ".temp"; | 
| + | 
| +// Sleep between wallpaper retries (used multiplied by retry number). | 
| +const unsigned kRetrySleepSeconds = 10; | 
| + | 
| +// Do not increase retry sleep beyond this number of attempts. | 
| +const unsigned kRetriesInfinite = 30; | 
| +} | 
| + | 
| +namespace chromeos { | 
| + | 
| +CustomizationWallpaperDownloader::CustomizationWallpaperDownloader( | 
| +    net::URLRequestContextGetter* url_context_getter, | 
| +    const GURL& wallpaper_url, | 
| +    const base::FilePath& wallpaper_dir, | 
| +    const base::FilePath& wallpaper_downloaded_file) | 
| +    : url_context_getter_(url_context_getter), | 
| +      wallpaper_url_(wallpaper_url), | 
| +      wallpaper_dir_(wallpaper_dir), | 
| +      wallpaper_downloaded_file_(wallpaper_downloaded_file), | 
| +      wallpaper_temporary_file_(wallpaper_downloaded_file.value() + | 
| +                                kTemporarySuffix), | 
| +      retries_(0), | 
| +      weak_factory_(this) { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +} | 
| + | 
| +CustomizationWallpaperDownloader::~CustomizationWallpaperDownloader() { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::StartRequest() { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  DCHECK(wallpaper_url_.is_valid()); | 
| +  ++retries_; | 
| + | 
| +  url_fetcher_.reset( | 
| +      net::URLFetcher::Create(wallpaper_url_, net::URLFetcher::GET, this)); | 
| +  url_fetcher_->SetRequestContext(url_context_getter_); | 
| +  url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | | 
| +                             net::LOAD_DO_NOT_SAVE_COOKIES | | 
| +                             net::LOAD_DO_NOT_SEND_COOKIES | | 
| +                             net::LOAD_DO_NOT_SEND_AUTH_DATA); | 
| +  base::SequencedWorkerPool* blocking_pool = | 
| +      content::BrowserThread::GetBlockingPool(); | 
| +  url_fetcher_->SaveResponseToFileAtPath( | 
| +      wallpaper_temporary_file_, | 
| +      blocking_pool->GetSequencedTaskRunner(blocking_pool->GetSequenceToken())); | 
| +  url_fetcher_->Start(); | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::Retry() { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  const unsigned delay_multiplier = | 
| +      (retries_ > kRetriesInfinite ? kRetriesInfinite : retries_); | 
| +  const base::TimeDelta delay = | 
| +      base::TimeDelta::FromSeconds(kRetrySleepSeconds) * delay_multiplier; | 
| +  VLOG(1) << "Schedule Customized Wallpaper download in " << delay.InSecondsF() | 
| +          << " seconds."; | 
| +  request_scheduled_.Start( | 
| +      FROM_HERE, delay, this, &CustomizationWallpaperDownloader::StartRequest); | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::Start() { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  scoped_ptr<bool> success(new bool(false)); | 
| + | 
| +  base::Closure mkdir_closure = | 
| +      base::Bind(&CustomizationWallpaperDownloader::CreateWallpaperDirectory, | 
| +                 wallpaper_dir_, | 
| +                 base::Unretained(success.get())); | 
| +  base::Closure on_created_closure = | 
| +      base::Bind(&CustomizationWallpaperDownloader::OnWallpaperDirectoryCreated, | 
| +                 weak_factory_.GetWeakPtr(), | 
| +                 base::Passed(success.Pass())); | 
| +  if (!content::BrowserThread::PostBlockingPoolTaskAndReply( | 
| +          FROM_HERE, mkdir_closure, on_created_closure)) { | 
| +    LOG(WARNING) << "Failed to start Customized Wallpaper download."; | 
| +  } | 
| +} | 
| + | 
| +// static | 
| +void CustomizationWallpaperDownloader::CreateWallpaperDirectory( | 
| +    const base::FilePath& wallpaper_dir, | 
| +    bool* success) { | 
| +  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 
| +  DCHECK(success); | 
| + | 
| +  *success = CreateDirectoryAndGetError(wallpaper_dir, NULL); | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::OnWallpaperDirectoryCreated( | 
| +    scoped_ptr<bool> success) { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  if (*success) | 
| +    StartRequest(); | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::OnURLFetchComplete( | 
| +    const net::URLFetcher* source) { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  DCHECK_EQ(url_fetcher_.get(), source); | 
| + | 
| +  const net::URLRequestStatus status = source->GetStatus(); | 
| +  const int response_code = source->GetResponseCode(); | 
| + | 
| +  const bool server_error = | 
| +      !status.is_success() || (response_code >= 500 && response_code < 600); | 
| + | 
| +  VLOG(1) << "CustomizationWallpaperDownloader::OnURLFetchComplete(): status=" | 
| +          << status.status(); | 
| + | 
| +  if (server_error) { | 
| +    url_fetcher_.reset(); | 
| +    Retry(); | 
| +    return; | 
| +  } | 
| + | 
| +  base::FilePath response_path; | 
| +  url_fetcher_->GetResponseAsFilePath(true, &response_path); | 
| +  url_fetcher_.reset(); | 
| + | 
| +  scoped_ptr<bool> success(new bool(false)); | 
| + | 
| +  base::Closure rename_closure = | 
| +      base::Bind(&CustomizationWallpaperDownloader::RenameTemporaryFile, | 
| +                 response_path, | 
| +                 wallpaper_downloaded_file_, | 
| +                 base::Unretained(success.get())); | 
| +  base::Closure on_rename_closure = | 
| +      base::Bind(&CustomizationWallpaperDownloader::OnTemporaryFileRenamed, | 
| +                 weak_factory_.GetWeakPtr(), | 
| +                 base::Passed(success.Pass())); | 
| +  if (!content::BrowserThread::PostBlockingPoolTaskAndReply( | 
| +          FROM_HERE, rename_closure, on_rename_closure)) { | 
| +    LOG(WARNING) | 
| +        << "Failed to start Customized Wallpaper Rename DownloadedFile."; | 
| +    // Destroy self. | 
| +    ServicesCustomizationDocument::GetInstance()->DestroyWallpaperDownloader(); | 
| +  } | 
| +} | 
| + | 
| +void CustomizationWallpaperDownloader::OnTemporaryFileRenamed( | 
| +    scoped_ptr<bool> success) { | 
| +  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
| +  if (!success) { | 
| +    // Destroy self. | 
| +    ServicesCustomizationDocument::GetInstance()->DestroyWallpaperDownloader(); | 
| +    return; | 
| +  } | 
| +  ServicesCustomizationDocument::OnCustomizedWallpaperDownloaded( | 
| +      wallpaper_url_); | 
| +} | 
| + | 
| +// static | 
| +void CustomizationWallpaperDownloader::RenameTemporaryFile( | 
| +    const base::FilePath& from, | 
| +    const base::FilePath& to, | 
| +    bool* success) { | 
| +  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 
| +  DCHECK(success); | 
| + | 
| +  base::File::Error error; | 
| +  if (ReplaceFile(from, to, &error)) { | 
| +    *success = true; | 
| +  } else { | 
| +    LOG(WARNING) | 
| +        << "Failed to rename temporary file of Customized Wallpaper. error=" | 
| +        << error; | 
| +    *success = false; | 
| +  } | 
| +} | 
| + | 
| +}  //   namespace chromeos | 
|  |