Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / image_writer_private / write_from_url_operation.cc
blobb220af0bdfc7382ba3184f7137d1318473b23235
1 // Copyright 2013 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 "base/files/file_util.h"
6 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
7 #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
8 #include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "net/url_request/url_fetcher.h"
12 namespace extensions {
13 namespace image_writer {
15 using content::BrowserThread;
17 WriteFromUrlOperation::WriteFromUrlOperation(
18 base::WeakPtr<OperationManager> manager,
19 const ExtensionId& extension_id,
20 net::URLRequestContextGetter* request_context,
21 GURL url,
22 const std::string& hash,
23 const std::string& device_path)
24 : Operation(manager, extension_id, device_path),
25 request_context_(request_context),
26 url_(url),
27 hash_(hash),
28 download_continuation_() {}
30 WriteFromUrlOperation::~WriteFromUrlOperation() {
33 void WriteFromUrlOperation::StartImpl() {
34 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
36 GetDownloadTarget(base::Bind(
37 &WriteFromUrlOperation::Download,
38 this,
39 base::Bind(
40 &WriteFromUrlOperation::VerifyDownload,
41 this,
42 base::Bind(
43 &WriteFromUrlOperation::Unzip,
44 this,
45 base::Bind(&WriteFromUrlOperation::Write,
46 this,
47 base::Bind(&WriteFromUrlOperation::VerifyWrite,
48 this,
49 base::Bind(&WriteFromUrlOperation::Finish,
50 this)))))));
53 void WriteFromUrlOperation::GetDownloadTarget(
54 const base::Closure& continuation) {
55 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
56 if (IsCancelled()) {
57 return;
60 if (url_.ExtractFileName().empty()) {
61 if (!base::CreateTemporaryFileInDir(temp_dir_.path(), &image_path_)) {
62 Error(error::kTempFileError);
63 return;
65 } else {
66 base::FilePath file_name =
67 base::FilePath::FromUTF8Unsafe(url_.ExtractFileName());
68 image_path_ = temp_dir_.path().Append(file_name);
71 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation);
74 void WriteFromUrlOperation::Download(const base::Closure& continuation) {
75 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
77 if (IsCancelled()) {
78 return;
81 download_continuation_ = continuation;
83 SetStage(image_writer_api::STAGE_DOWNLOAD);
85 // Store the URL fetcher on this object so that it is destroyed before this
86 // object is.
87 url_fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::GET, this);
89 url_fetcher_->SetRequestContext(request_context_);
90 url_fetcher_->SaveResponseToFileAtPath(
91 image_path_,
92 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
94 AddCleanUpFunction(
95 base::Bind(&WriteFromUrlOperation::DestroyUrlFetcher, this));
97 url_fetcher_->Start();
100 void WriteFromUrlOperation::DestroyUrlFetcher() { url_fetcher_.reset(); }
102 void WriteFromUrlOperation::OnURLFetchUploadProgress(
103 const net::URLFetcher* source,
104 int64 current,
105 int64 total) {
106 // No-op
109 void WriteFromUrlOperation::OnURLFetchDownloadProgress(
110 const net::URLFetcher* source,
111 int64 current,
112 int64 total) {
113 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
115 if (IsCancelled()) {
116 url_fetcher_.reset(NULL);
119 int progress = (kProgressComplete * current) / total;
121 SetProgress(progress);
124 void WriteFromUrlOperation::OnURLFetchComplete(const net::URLFetcher* source) {
125 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
127 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
128 SetProgress(kProgressComplete);
130 download_continuation_.Run();
132 // Remove the reference to ourselves in this closure.
133 download_continuation_ = base::Closure();
134 } else {
135 Error(error::kDownloadInterrupted);
139 void WriteFromUrlOperation::VerifyDownload(const base::Closure& continuation) {
140 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
142 if (IsCancelled()) {
143 return;
146 // Skip verify if no hash.
147 if (hash_.empty()) {
148 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation);
149 return;
152 SetStage(image_writer_api::STAGE_VERIFYDOWNLOAD);
154 GetMD5SumOfFile(
155 image_path_,
158 kProgressComplete,
159 base::Bind(
160 &WriteFromUrlOperation::VerifyDownloadCompare, this, continuation));
163 void WriteFromUrlOperation::VerifyDownloadCompare(
164 const base::Closure& continuation,
165 const std::string& download_hash) {
166 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
167 if (download_hash != hash_) {
168 Error(error::kDownloadHashError);
169 return;
172 BrowserThread::PostTask(
173 BrowserThread::FILE,
174 FROM_HERE,
175 base::Bind(
176 &WriteFromUrlOperation::VerifyDownloadComplete, this, continuation));
179 void WriteFromUrlOperation::VerifyDownloadComplete(
180 const base::Closure& continuation) {
181 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
182 if (IsCancelled()) {
183 return;
186 SetProgress(kProgressComplete);
187 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation);
190 } // namespace image_writer
191 } // namespace extensions