Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1060)

Side by Side Diff: chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc

Issue 170123002: Revert of Significantly cleans up the ImageWriter Operation class and subclasses. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/threading/worker_pool.h"
7 #include "chrome/browser/browser_process.h"
6 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h" 8 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
7 #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h " 9 #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h "
8 #include "chrome/browser/extensions/api/image_writer_private/write_from_url_oper ation.h" 10 #include "chrome/browser/extensions/api/image_writer_private/write_from_url_oper ation.h"
11 #include "chrome/browser/profiles/profile.h"
9 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
10 #include "net/url_request/url_fetcher.h" 13 #include "content/public/browser/download_manager.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "extensions/common/error_utils.h"
11 17
12 namespace extensions { 18 namespace extensions {
13 namespace image_writer { 19 namespace image_writer {
14 20
15 using content::BrowserThread; 21 using content::BrowserThread;
16 22
17 WriteFromUrlOperation::WriteFromUrlOperation( 23 WriteFromUrlOperation::WriteFromUrlOperation(
18 base::WeakPtr<OperationManager> manager, 24 base::WeakPtr<OperationManager> manager,
19 const ExtensionId& extension_id, 25 const ExtensionId& extension_id,
20 net::URLRequestContextGetter* request_context, 26 content::RenderViewHost* rvh,
21 GURL url, 27 GURL url,
22 const std::string& hash, 28 const std::string& hash,
23 const std::string& device_path) 29 bool saveImageAsDownload,
24 : Operation(manager, extension_id, device_path), 30 const std::string& storage_unit_id)
25 request_context_(request_context), 31 : Operation(manager, extension_id, storage_unit_id),
32 rvh_(rvh),
26 url_(url), 33 url_(url),
27 hash_(hash), 34 hash_(hash),
28 download_continuation_() {} 35 saveImageAsDownload_(saveImageAsDownload),
36 download_stopped_(false),
37 download_(NULL) {
38 }
29 39
30 WriteFromUrlOperation::~WriteFromUrlOperation() { 40 WriteFromUrlOperation::~WriteFromUrlOperation() {
31 } 41 }
32 42
33 void WriteFromUrlOperation::StartImpl() { 43 void WriteFromUrlOperation::Start() {
34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
35 45
36 GetDownloadTarget(base::Bind( 46 SetStage(image_writer_api::STAGE_DOWNLOAD);
37 &WriteFromUrlOperation::Download, 47
38 this, 48 if (saveImageAsDownload_){
39 base::Bind( 49 BrowserThread::PostTask(
40 &WriteFromUrlOperation::VerifyDownload, 50 BrowserThread::UI,
41 this, 51 FROM_HERE,
42 base::Bind( 52 base::Bind(&WriteFromUrlOperation::DownloadStart, this));
43 &WriteFromUrlOperation::Unzip, 53 } else {
44 this, 54 BrowserThread::PostTask(
45 base::Bind(&WriteFromUrlOperation::Write, 55 BrowserThread::FILE,
46 this, 56 FROM_HERE,
47 base::Bind(&WriteFromUrlOperation::VerifyWrite, 57 base::Bind(&WriteFromUrlOperation::CreateTempFile, this));
48 this, 58 }
49 base::Bind(&WriteFromUrlOperation::Finish, 59
50 this))))))); 60 AddCleanUpFunction(base::Bind(&WriteFromUrlOperation::DownloadCleanUp, this));
51 } 61 }
52 62
53 void WriteFromUrlOperation::GetDownloadTarget( 63 void WriteFromUrlOperation::CreateTempFile() {
54 const base::Closure& continuation) {
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
56 if (IsCancelled()) { 64 if (IsCancelled()) {
57 return; 65 return;
58 } 66 }
59 67
60 if (url_.ExtractFileName() == "") { 68 tmp_file_.reset(new base::FilePath());
61 if (!base::CreateTemporaryFileInDir(temp_dir_.path(), &image_path_)) { 69
62 Error(error::kTempFileError); 70 if (base::CreateTemporaryFile(tmp_file_.get())) {
63 return; 71 BrowserThread::PostTask(
64 } 72 BrowserThread::UI,
73 FROM_HERE,
74 base::Bind(&WriteFromUrlOperation::DownloadStart, this));
65 } else { 75 } else {
66 base::FilePath file_name = 76 Error(error::kTempFileError);
67 base::FilePath::FromUTF8Unsafe(url_.ExtractFileName()); 77 }
68 image_path_ = temp_dir_.path().Append(file_name); 78 }
79
80 // The downloader runs on the UI thread.
81 void WriteFromUrlOperation::DownloadStart() {
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83
84 if (download_stopped_) {
85 return;
69 } 86 }
70 87
71 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation); 88 DVLOG(1) << "Starting download of URL: " << url_;
89
90 Profile* current_profile = manager_->profile();
91
92 scoped_ptr<content::DownloadUrlParameters> download_params(
93 new content::DownloadUrlParameters(
94 url_,
95 rvh_->GetProcess()->GetID(),
96 rvh_->GetRoutingID(),
97 current_profile->GetResourceContext()));
98
99 if (tmp_file_.get()) {
100 download_params->set_file_path(*tmp_file_);
101 }
102
103 download_params->set_callback(
104 base::Bind(&WriteFromUrlOperation::OnDownloadStarted, this));
105
106 content::DownloadManager* download_manager =
107 content::BrowserContext::GetDownloadManager(current_profile);
108 download_manager->DownloadUrl(download_params.Pass());
72 } 109 }
73 110
74 void WriteFromUrlOperation::Download(const base::Closure& continuation) { 111 void WriteFromUrlOperation::OnDownloadStarted(
112 content::DownloadItem* item,
113 content::DownloadInterruptReason interrupt_reason) {
114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115
116 if (download_stopped_) {
117 // At this point DownloadCleanUp was called but the |download_| wasn't
118 // stored yet and still hasn't been cancelled.
119 item->Cancel(true);
120 return;
121 }
122
123 if (item) {
124 DCHECK_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
125
126 download_ = item;
127 download_->AddObserver(this);
128
129 // Run at least once.
130 OnDownloadUpdated(download_);
131 } else {
132 DCHECK_NE(content::DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
133 std::string error_message = ErrorUtils::FormatErrorMessage(
134 "Download failed: *",
135 content::DownloadInterruptReasonToString(interrupt_reason));
136 Error(error_message);
137 }
138 }
139
140 // Always called from the UI thread.
141 void WriteFromUrlOperation::OnDownloadUpdated(content::DownloadItem* download) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143
144 if (download_stopped_) {
145 return;
146 }
147
148 SetProgress(download->PercentComplete());
149
150 if (download->GetState() == content::DownloadItem::COMPLETE) {
151 download_path_ = download_->GetTargetFilePath();
152
153 download_->RemoveObserver(this);
154 download_ = NULL;
155
156 BrowserThread::PostTask(
157 BrowserThread::FILE,
158 FROM_HERE,
159 base::Bind(&WriteFromUrlOperation::DownloadComplete, this));
160
161 } else if (download->GetState() == content::DownloadItem::INTERRUPTED) {
162 Error(error::kDownloadInterrupted);
163 } else if (download->GetState() == content::DownloadItem::CANCELLED) {
164 Error(error::kDownloadCancelled);
165 }
166 }
167
168 void WriteFromUrlOperation::DownloadComplete() {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
170 DVLOG(1) << "Download complete.";
171
172 SetProgress(kProgressComplete);
173
174 VerifyDownloadStart();
175 }
176
177 void WriteFromUrlOperation::DownloadCleanUp() {
178 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
179 BrowserThread::PostTask(
180 BrowserThread::UI,
181 FROM_HERE,
182 base::Bind(&WriteFromUrlOperation::DownloadCleanUp, this));
183 return;
184 }
185
186 download_stopped_ = true;
187
188 if (download_) {
189 download_->RemoveObserver(this);
190 download_->Cancel(true);
191 download_ = NULL;
192 }
193 }
194
195 void WriteFromUrlOperation::VerifyDownloadStart() {
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
76 197
77 if (IsCancelled()) { 198 if (IsCancelled()) {
78 return;
79 }
80
81 download_continuation_ = continuation;
82
83 SetStage(image_writer_api::STAGE_DOWNLOAD);
84
85 // Store the URL fetcher on this object so that it is destroyed before this
86 // object is.
87 url_fetcher_.reset(net::URLFetcher::Create(url_, net::URLFetcher::GET, this));
88
89 url_fetcher_->SetRequestContext(request_context_);
90 url_fetcher_->SaveResponseToFileAtPath(
91 image_path_,
92 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
93
94 AddCleanUpFunction(
95 base::Bind(&WriteFromUrlOperation::DestroyUrlFetcher, this));
96
97 url_fetcher_->Start();
98 }
99
100 void WriteFromUrlOperation::DestroyUrlFetcher() { url_fetcher_.reset(); }
101
102 void WriteFromUrlOperation::OnURLFetchUploadProgress(
103 const net::URLFetcher* source,
104 int64 current,
105 int64 total) {
106 // No-op
107 }
108
109 void WriteFromUrlOperation::OnURLFetchDownloadProgress(
110 const net::URLFetcher* source,
111 int64 current,
112 int64 total) {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
114
115 if (IsCancelled()) {
116 url_fetcher_.reset(NULL);
117 }
118
119 int progress = (kProgressComplete * current) / total;
120
121 SetProgress(progress);
122 }
123
124 void WriteFromUrlOperation::OnURLFetchComplete(const net::URLFetcher* source) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
126
127 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
128 SetProgress(kProgressComplete);
129
130 download_continuation_.Run();
131
132 // Remove the reference to ourselves in this closure.
133 download_continuation_ = base::Closure();
134 } else {
135 Error(error::kDownloadInterrupted);
136 }
137 }
138
139 void WriteFromUrlOperation::VerifyDownload(const base::Closure& continuation) {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
141
142 if (IsCancelled()) {
143 return; 199 return;
144 } 200 }
145 201
146 // Skip verify if no hash. 202 // Skip verify if no hash.
147 if (hash_.empty()) { 203 if (hash_.empty()) {
148 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation); 204 scoped_ptr<base::FilePath> download_path(
205 new base::FilePath(download_path_));
206 UnzipStart(download_path.Pass());
149 return; 207 return;
150 } 208 }
151 209
210 DVLOG(1) << "Download verification started.";
211
152 SetStage(image_writer_api::STAGE_VERIFYDOWNLOAD); 212 SetStage(image_writer_api::STAGE_VERIFYDOWNLOAD);
153 213
214 BrowserThread::PostTask(
215 BrowserThread::FILE,
216 FROM_HERE,
217 base::Bind(&WriteFromUrlOperation::VerifyDownloadRun, this));
218 }
219
220 void WriteFromUrlOperation::VerifyDownloadRun() {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
222 scoped_ptr<base::FilePath> download_path(new base::FilePath(download_path_));
154 GetMD5SumOfFile( 223 GetMD5SumOfFile(
155 image_path_, 224 download_path.Pass(),
156 0, 225 0,
157 0, 226 0,
158 kProgressComplete, 227 kProgressComplete,
159 base::Bind( 228 base::Bind(&WriteFromUrlOperation::VerifyDownloadCompare, this));
160 &WriteFromUrlOperation::VerifyDownloadCompare, this, continuation));
161 } 229 }
162 230
163 void WriteFromUrlOperation::VerifyDownloadCompare( 231 void WriteFromUrlOperation::VerifyDownloadCompare(
164 const base::Closure& continuation, 232 scoped_ptr<std::string> download_hash) {
165 const std::string& download_hash) {
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
167 if (download_hash != hash_) { 234 if (*download_hash != hash_) {
168 Error(error::kDownloadHashError); 235 Error(error::kDownloadHashError);
169 return; 236 return;
170 } 237 }
171 238
172 BrowserThread::PostTask( 239 BrowserThread::PostTask(
173 BrowserThread::FILE, 240 BrowserThread::FILE,
174 FROM_HERE, 241 FROM_HERE,
175 base::Bind( 242 base::Bind(&WriteFromUrlOperation::VerifyDownloadComplete, this));
176 &WriteFromUrlOperation::VerifyDownloadComplete, this, continuation));
177 } 243 }
178 244
179 void WriteFromUrlOperation::VerifyDownloadComplete( 245 void WriteFromUrlOperation::VerifyDownloadComplete() {
180 const base::Closure& continuation) {
181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
182 if (IsCancelled()) { 247 if (IsCancelled()) {
183 return; 248 return;
184 } 249 }
185 250
251 DVLOG(1) << "Download verification complete.";
252
186 SetProgress(kProgressComplete); 253 SetProgress(kProgressComplete);
187 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation); 254
255 scoped_ptr<base::FilePath> download_path(new base::FilePath(download_path_));
256 UnzipStart(download_path.Pass());
188 } 257 }
189 258
190 } // namespace image_writer 259 } // namespace image_writer
191 } // namespace extensions 260 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698