Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / customization / customization_wallpaper_downloader.cc
blob08537c6e8edae86d07825e76afcbbc70c81a47c4
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/customization/customization_wallpaper_downloader.h"
7 #include <math.h>
8 #include <algorithm>
10 #include "base/files/file_util.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "net/base/load_flags.h"
13 #include "net/http/http_status_code.h"
14 #include "net/url_request/url_fetcher.h"
15 #include "net/url_request/url_request_context_getter.h"
16 #include "url/gurl.h"
18 namespace chromeos {
19 namespace {
20 // This is temporary file suffix (for downloading or resizing).
21 const char kTemporarySuffix[] = ".tmp";
23 // Sleep between wallpaper retries (used multiplied by squared retry number).
24 const unsigned kRetrySleepSeconds = 10;
26 // Retry is infinite with increasing intervals. When calculated delay becomes
27 // longer than maximum (kMaxRetrySleepSeconds) it is set to the maximum.
28 const double kMaxRetrySleepSeconds = 6 * 3600; // 6 hours
30 void CreateWallpaperDirectory(const base::FilePath& wallpaper_dir,
31 bool* success) {
32 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
33 DCHECK(success);
35 *success = CreateDirectoryAndGetError(wallpaper_dir, NULL);
36 if (!*success) {
37 NOTREACHED() << "Failed to create directory '" << wallpaper_dir.value()
38 << "'";
42 void RenameTemporaryFile(const base::FilePath& from,
43 const base::FilePath& to,
44 bool* success) {
45 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
46 DCHECK(success);
48 base::File::Error error;
49 if (base::ReplaceFile(from, to, &error)) {
50 *success = true;
51 } else {
52 LOG(WARNING)
53 << "Failed to rename temporary file of Customized Wallpaper. error="
54 << error;
55 *success = false;
59 } // namespace
61 CustomizationWallpaperDownloader::CustomizationWallpaperDownloader(
62 net::URLRequestContextGetter* url_context_getter,
63 const GURL& wallpaper_url,
64 const base::FilePath& wallpaper_dir,
65 const base::FilePath& wallpaper_downloaded_file,
66 base::Callback<void(bool success, const GURL&)>
67 on_wallpaper_fetch_completed)
68 : url_context_getter_(url_context_getter),
69 wallpaper_url_(wallpaper_url),
70 wallpaper_dir_(wallpaper_dir),
71 wallpaper_downloaded_file_(wallpaper_downloaded_file),
72 wallpaper_temporary_file_(wallpaper_downloaded_file.value() +
73 kTemporarySuffix),
74 retries_(0),
75 retry_delay_(base::TimeDelta::FromSeconds(kRetrySleepSeconds)),
76 on_wallpaper_fetch_completed_(on_wallpaper_fetch_completed),
77 weak_factory_(this) {
78 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
81 CustomizationWallpaperDownloader::~CustomizationWallpaperDownloader() {
82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
85 void CustomizationWallpaperDownloader::StartRequest() {
86 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
87 DCHECK(wallpaper_url_.is_valid());
89 url_fetcher_ =
90 net::URLFetcher::Create(wallpaper_url_, net::URLFetcher::GET, this);
91 url_fetcher_->SetRequestContext(url_context_getter_.get());
92 url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE |
93 net::LOAD_DISABLE_CACHE |
94 net::LOAD_DO_NOT_SAVE_COOKIES |
95 net::LOAD_DO_NOT_SEND_COOKIES |
96 net::LOAD_DO_NOT_SEND_AUTH_DATA);
97 base::SequencedWorkerPool* blocking_pool =
98 content::BrowserThread::GetBlockingPool();
99 url_fetcher_->SaveResponseToFileAtPath(
100 wallpaper_temporary_file_,
101 blocking_pool->GetSequencedTaskRunner(blocking_pool->GetSequenceToken()));
102 url_fetcher_->Start();
105 void CustomizationWallpaperDownloader::Retry() {
106 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
107 ++retries_;
109 const double delay_seconds = std::min(
110 kMaxRetrySleepSeconds,
111 static_cast<double>(retries_) * retries_ * retry_delay_.InSecondsF());
112 const base::TimeDelta delay = base::TimeDelta::FromSecondsD(delay_seconds);
114 VLOG(1) << "Schedule Customized Wallpaper download in " << delay.InSecondsF()
115 << " seconds (retry = " << retries_ << ").";
116 retry_current_delay_ = delay;
117 request_scheduled_.Start(
118 FROM_HERE, delay, this, &CustomizationWallpaperDownloader::StartRequest);
121 void CustomizationWallpaperDownloader::Start() {
122 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
123 scoped_ptr<bool> success(new bool(false));
125 base::Closure mkdir_closure = base::Bind(&CreateWallpaperDirectory,
126 wallpaper_dir_,
127 base::Unretained(success.get()));
128 base::Closure on_created_closure =
129 base::Bind(&CustomizationWallpaperDownloader::OnWallpaperDirectoryCreated,
130 weak_factory_.GetWeakPtr(),
131 base::Passed(success.Pass()));
132 if (!content::BrowserThread::PostBlockingPoolTaskAndReply(
133 FROM_HERE, mkdir_closure, on_created_closure)) {
134 LOG(WARNING) << "Failed to start Customized Wallpaper download.";
138 void CustomizationWallpaperDownloader::OnWallpaperDirectoryCreated(
139 scoped_ptr<bool> success) {
140 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
141 if (*success)
142 StartRequest();
145 void CustomizationWallpaperDownloader::OnURLFetchComplete(
146 const net::URLFetcher* source) {
147 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
148 DCHECK_EQ(url_fetcher_.get(), source);
150 const net::URLRequestStatus status = source->GetStatus();
151 const int response_code = source->GetResponseCode();
153 const bool server_error =
154 !status.is_success() ||
155 (response_code >= net::HTTP_INTERNAL_SERVER_ERROR &&
156 response_code < (net::HTTP_INTERNAL_SERVER_ERROR + 100));
158 VLOG(1) << "CustomizationWallpaperDownloader::OnURLFetchComplete(): status="
159 << status.status();
161 if (server_error) {
162 url_fetcher_.reset();
163 Retry();
164 return;
167 base::FilePath response_path;
168 url_fetcher_->GetResponseAsFilePath(true, &response_path);
169 url_fetcher_.reset();
171 scoped_ptr<bool> success(new bool(false));
173 base::Closure rename_closure = base::Bind(&RenameTemporaryFile,
174 response_path,
175 wallpaper_downloaded_file_,
176 base::Unretained(success.get()));
177 base::Closure on_rename_closure =
178 base::Bind(&CustomizationWallpaperDownloader::OnTemporaryFileRenamed,
179 weak_factory_.GetWeakPtr(),
180 base::Passed(success.Pass()));
181 if (!content::BrowserThread::PostBlockingPoolTaskAndReply(
182 FROM_HERE, rename_closure, on_rename_closure)) {
183 LOG(WARNING)
184 << "Failed to start Customized Wallpaper Rename DownloadedFile.";
185 on_wallpaper_fetch_completed_.Run(false, wallpaper_url_);
189 void CustomizationWallpaperDownloader::OnTemporaryFileRenamed(
190 scoped_ptr<bool> success) {
191 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
192 on_wallpaper_fetch_completed_.Run(*success, wallpaper_url_);
195 } // namespace chromeos