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

Side by Side Diff: content/browser/download/download_file_impl.cc

Issue 10799005: Replace the DownloadFileManager with direct ownership (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed Windows compile error. Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/download/download_file_impl.h" 5 #include "content/browser/download/download_file_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/message_loop_proxy.h" 11 #include "base/message_loop_proxy.h"
12 #include "base/time.h" 12 #include "base/time.h"
13 #include "content/browser/download/byte_stream.h" 13 #include "content/browser/download/byte_stream.h"
14 #include "content/browser/download/download_create_info.h" 14 #include "content/browser/download/download_create_info.h"
15 #include "content/browser/download/download_interrupt_reasons_impl.h" 15 #include "content/browser/download/download_interrupt_reasons_impl.h"
16 #include "content/browser/download/download_net_log_parameters.h" 16 #include "content/browser/download/download_net_log_parameters.h"
17 #include "content/browser/power_save_blocker.h" 17 #include "content/browser/power_save_blocker.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/download_manager.h" 19 #include "content/public/browser/download_destination_observer.h"
20 #include "content/browser/download/download_stats.h" 20 #include "content/browser/download/download_stats.h"
21 #include "net/base/io_buffer.h" 21 #include "net/base/io_buffer.h"
22 22
23 using content::BrowserThread; 23 using content::BrowserThread;
24 using content::DownloadId; 24 using content::DownloadId;
25 using content::DownloadManager; 25 using content::DownloadManager;
26 26
27 const int kUpdatePeriodMs = 500; 27 const int kUpdatePeriodMs = 500;
28 const int kMaxTimeBlockingFileThreadMs = 1000; 28 const int kMaxTimeBlockingFileThreadMs = 1000;
29 29
30 int content::DownloadFile::number_active_objects_ = 0;
31
30 DownloadFileImpl::DownloadFileImpl( 32 DownloadFileImpl::DownloadFileImpl(
31 const DownloadCreateInfo* info, 33 const content::DownloadSaveInfo& save_info,
34 const GURL& url,
35 const GURL& referrer_url,
36 int64 received_bytes,
37 bool calculate_hash,
32 scoped_ptr<content::ByteStreamReader> stream, 38 scoped_ptr<content::ByteStreamReader> stream,
33 DownloadRequestHandleInterface* request_handle, 39 const net::BoundNetLog& bound_net_log,
34 scoped_refptr<DownloadManager> download_manager,
35 bool calculate_hash,
36 scoped_ptr<content::PowerSaveBlocker> power_save_blocker, 40 scoped_ptr<content::PowerSaveBlocker> power_save_blocker,
37 const net::BoundNetLog& bound_net_log) 41 base::WeakPtr<content::DownloadDestinationObserver> observer)
38 : file_(info->save_info.file_path, 42 : file_(save_info.file_path,
39 info->url(), 43 url,
40 info->referrer_url, 44 referrer_url,
41 info->received_bytes, 45 received_bytes,
42 calculate_hash, 46 calculate_hash,
43 info->save_info.hash_state, 47 save_info.hash_state,
44 info->save_info.file_stream, 48 save_info.file_stream,
45 bound_net_log), 49 bound_net_log),
46 stream_reader_(stream.Pass()), 50 stream_reader_(stream.Pass()),
47 id_(info->download_id),
48 request_handle_(request_handle),
49 download_manager_(download_manager),
50 bytes_seen_(0), 51 bytes_seen_(0),
51 bound_net_log_(bound_net_log), 52 bound_net_log_(bound_net_log),
53 observer_(observer),
52 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 54 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
53 power_save_blocker_(power_save_blocker.Pass()) { 55 power_save_blocker_(power_save_blocker.Pass()) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
55 DCHECK(download_manager.get());
56 } 56 }
57 57
58 DownloadFileImpl::~DownloadFileImpl() { 58 DownloadFileImpl::~DownloadFileImpl() {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
60 --number_active_objects_;
59 } 61 }
60 62
61 content::DownloadInterruptReason DownloadFileImpl::Initialize() { 63 void DownloadFileImpl::Initialize(const InitializeCallback& callback) {
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
65
62 update_timer_.reset(new base::RepeatingTimer<DownloadFileImpl>()); 66 update_timer_.reset(new base::RepeatingTimer<DownloadFileImpl>());
63 net::Error result = file_.Initialize(); 67
64 if (result != net::OK) { 68 net::Error net_result = file_.Initialize();
65 return content::ConvertNetErrorToInterruptReason( 69 if (net_result != net::OK) {
66 result, content::DOWNLOAD_INTERRUPT_FROM_DISK); 70 BrowserThread::PostTask(
71 BrowserThread::UI, FROM_HERE, base::Bind(
72 callback, content::ConvertNetErrorToInterruptReason(
73 net_result, content::DOWNLOAD_INTERRUPT_FROM_DISK)));
74 return;
67 } 75 }
68 76
69 stream_reader_->RegisterCallback( 77 stream_reader_->RegisterCallback(
70 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr())); 78 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr()));
71 79
72 download_start_ = base::TimeTicks::Now(); 80 download_start_ = base::TimeTicks::Now();
81
73 // Initial pull from the straw. 82 // Initial pull from the straw.
74 StreamActive(); 83 StreamActive();
75 84
76 return content::DOWNLOAD_INTERRUPT_REASON_NONE; 85 BrowserThread::PostTask(
86 BrowserThread::UI, FROM_HERE, base::Bind(
87 callback, content::DOWNLOAD_INTERRUPT_REASON_NONE));
88
89 ++number_active_objects_;
77 } 90 }
78 91
79 content::DownloadInterruptReason DownloadFileImpl::AppendDataToFile( 92 content::DownloadInterruptReason DownloadFileImpl::AppendDataToFile(
80 const char* data, size_t data_len) { 93 const char* data, size_t data_len) {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
95
81 if (!update_timer_->IsRunning()) { 96 if (!update_timer_->IsRunning()) {
82 update_timer_->Start(FROM_HERE, 97 update_timer_->Start(FROM_HERE,
83 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 98 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
84 this, &DownloadFileImpl::SendUpdate); 99 this, &DownloadFileImpl::SendUpdate);
85 } 100 }
86 return content::ConvertNetErrorToInterruptReason( 101 return content::ConvertNetErrorToInterruptReason(
87 file_.AppendDataToFile(data, data_len), 102 file_.AppendDataToFile(data, data_len),
88 content::DOWNLOAD_INTERRUPT_FROM_DISK); 103 content::DOWNLOAD_INTERRUPT_FROM_DISK);
89 } 104 }
90 105
91 void DownloadFileImpl::Rename(const FilePath& full_path, 106 void DownloadFileImpl::Rename(const FilePath& full_path,
92 bool overwrite_existing_file, 107 bool overwrite_existing_file,
93 const RenameCompletionCallback& callback) { 108 const RenameCompletionCallback& callback) {
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
110
94 FilePath new_path(full_path); 111 FilePath new_path(full_path);
95 if (!overwrite_existing_file) { 112 if (!overwrite_existing_file) {
96 // Make the file unique if requested. 113 // Make the file unique if requested.
97 int uniquifier = 114 int uniquifier =
98 file_util::GetUniquePathNumber(new_path, FILE_PATH_LITERAL("")); 115 file_util::GetUniquePathNumber(new_path, FILE_PATH_LITERAL(""));
99 if (uniquifier > 0) { 116 if (uniquifier > 0) {
100 new_path = new_path.InsertBeforeExtensionASCII( 117 new_path = new_path.InsertBeforeExtensionASCII(
101 StringPrintf(" (%d)", uniquifier)); 118 StringPrintf(" (%d)", uniquifier));
102 } 119 }
103 } 120 }
(...skipping 15 matching lines...) Expand all
119 content::DOWNLOAD_INTERRUPT_FROM_DISK); 136 content::DOWNLOAD_INTERRUPT_FROM_DISK);
120 new_path.clear(); 137 new_path.clear();
121 } 138 }
122 139
123 BrowserThread::PostTask( 140 BrowserThread::PostTask(
124 BrowserThread::UI, FROM_HERE, 141 BrowserThread::UI, FROM_HERE,
125 base::Bind(callback, reason, new_path)); 142 base::Bind(callback, reason, new_path));
126 } 143 }
127 144
128 void DownloadFileImpl::Detach() { 145 void DownloadFileImpl::Detach() {
146 // Done here on Windows so that anti-virus scanners invoked by
147 // the attachment service actually see the data; see
148 // http://crbug.com/127999.
149 // Done here for mac because we only want to do this once; see
150 // http://crbug.com/13120 for details.
151 // Other platforms don't currently do source annotation.
152 AnnotateWithSourceInformation();
153
129 file_.Detach(); 154 file_.Detach();
130 } 155 }
131 156
132 void DownloadFileImpl::Cancel() { 157 void DownloadFileImpl::Cancel() {
133 file_.Cancel(); 158 file_.Cancel();
134 } 159 }
135 160
136 void DownloadFileImpl::AnnotateWithSourceInformation() { 161 void DownloadFileImpl::AnnotateWithSourceInformation() {
137 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED); 162 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED);
138 file_.AnnotateWithSourceInformation(); 163 file_.AnnotateWithSourceInformation();
(...skipping 17 matching lines...) Expand all
156 } 181 }
157 182
158 bool DownloadFileImpl::GetHash(std::string* hash) { 183 bool DownloadFileImpl::GetHash(std::string* hash) {
159 return file_.GetHash(hash); 184 return file_.GetHash(hash);
160 } 185 }
161 186
162 std::string DownloadFileImpl::GetHashState() { 187 std::string DownloadFileImpl::GetHashState() {
163 return file_.GetHashState(); 188 return file_.GetHashState();
164 } 189 }
165 190
166 // DownloadFileInterface implementation.
167 void DownloadFileImpl::CancelDownloadRequest() {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
169 request_handle_->CancelRequest();
170 }
171
172 int DownloadFileImpl::Id() const {
173 return id_.local();
174 }
175
176 DownloadManager* DownloadFileImpl::GetDownloadManager() {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
178 return download_manager_.get();
179 }
180
181 const DownloadId& DownloadFileImpl::GlobalId() const {
182 return id_;
183 }
184
185 std::string DownloadFileImpl::DebugString() const {
186 return base::StringPrintf("{"
187 " id_ = " "%d"
188 " request_handle = %s"
189 " Base File = %s"
190 " }",
191 id_.local(),
192 request_handle_->DebugString().c_str(),
193 file_.DebugString().c_str());
194 }
195
196 void DownloadFileImpl::StreamActive() { 191 void DownloadFileImpl::StreamActive() {
197 base::TimeTicks start(base::TimeTicks::Now()); 192 base::TimeTicks start(base::TimeTicks::Now());
198 base::TimeTicks now; 193 base::TimeTicks now;
199 scoped_refptr<net::IOBuffer> incoming_data; 194 scoped_refptr<net::IOBuffer> incoming_data;
200 size_t incoming_data_size = 0; 195 size_t incoming_data_size = 0;
201 size_t total_incoming_data_size = 0; 196 size_t total_incoming_data_size = 0;
202 size_t num_buffers = 0; 197 size_t num_buffers = 0;
203 content::ByteStreamReader::StreamState state( 198 content::ByteStreamReader::StreamState state(
204 content::ByteStreamReader::STREAM_EMPTY); 199 content::ByteStreamReader::STREAM_EMPTY);
205 content::DownloadInterruptReason reason = 200 content::DownloadInterruptReason reason =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 BrowserThread::FILE, FROM_HERE, 249 BrowserThread::FILE, FROM_HERE,
255 base::Bind(&DownloadFileImpl::StreamActive, 250 base::Bind(&DownloadFileImpl::StreamActive,
256 weak_factory_.GetWeakPtr())); 251 weak_factory_.GetWeakPtr()));
257 } 252 }
258 253
259 if (total_incoming_data_size) 254 if (total_incoming_data_size)
260 download_stats::RecordFileThreadReceiveBuffers(num_buffers); 255 download_stats::RecordFileThreadReceiveBuffers(num_buffers);
261 256
262 download_stats::RecordContiguousWriteTime(now - start); 257 download_stats::RecordContiguousWriteTime(now - start);
263 258
264 // Take care of communication with our controller. 259 // Take care of communication with our observer.
265 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { 260 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
266 // Error case for both upstream source and file write. 261 // Error case for both upstream source and file write.
267 // Shut down processing and signal an error to our controller. 262 // Shut down processing and signal an error to our observer.
268 // Our controller will clean us up. 263 // Our observer will clean us up.
269 stream_reader_->RegisterCallback(base::Closure()); 264 stream_reader_->RegisterCallback(base::Closure());
270 weak_factory_.InvalidateWeakPtrs(); 265 weak_factory_.InvalidateWeakPtrs();
271 SendUpdate(); // Make info up to date before error. 266 SendUpdate(); // Make info up to date before error.
272 BrowserThread::PostTask( 267 BrowserThread::PostTask(
273 BrowserThread::UI, FROM_HERE, 268 BrowserThread::UI, FROM_HERE,
274 base::Bind(&DownloadManager::OnDownloadInterrupted, 269 base::Bind(&content::DownloadDestinationObserver::DestinationError,
275 download_manager_, id_.local(), reason)); 270 observer_, reason));
276 } else if (state == content::ByteStreamReader::STREAM_COMPLETE) { 271 } else if (state == content::ByteStreamReader::STREAM_COMPLETE) {
277 // Signal successful completion and shut down processing. 272 // Signal successful completion and shut down processing.
278 stream_reader_->RegisterCallback(base::Closure()); 273 stream_reader_->RegisterCallback(base::Closure());
279 weak_factory_.InvalidateWeakPtrs(); 274 weak_factory_.InvalidateWeakPtrs();
280 std::string hash; 275 std::string hash;
281 if (!GetHash(&hash) || file_.IsEmptyHash(hash)) 276 if (!GetHash(&hash) || file_.IsEmptyHash(hash))
282 hash.clear(); 277 hash.clear();
278 SendUpdate();
283 BrowserThread::PostTask( 279 BrowserThread::PostTask(
284 BrowserThread::UI, FROM_HERE, 280 BrowserThread::UI, FROM_HERE,
285 base::Bind(&DownloadManager::OnResponseCompleted, 281 base::Bind(
286 download_manager_, id_.local(), 282 &content::DownloadDestinationObserver::DestinationCompleted,
287 BytesSoFar(), hash)); 283 observer_, hash));
288 } 284 }
289 if (bound_net_log_.IsLoggingAllEvents()) { 285 if (bound_net_log_.IsLoggingAllEvents()) {
290 bound_net_log_.AddEvent( 286 bound_net_log_.AddEvent(
291 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED, 287 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED,
292 base::Bind(&download_net_logs::FileStreamDrainedCallback, 288 base::Bind(&download_net_logs::FileStreamDrainedCallback,
293 total_incoming_data_size, num_buffers)); 289 total_incoming_data_size, num_buffers));
294 } 290 }
295 } 291 }
296 292
297 void DownloadFileImpl::SendUpdate() { 293 void DownloadFileImpl::SendUpdate() {
298 BrowserThread::PostTask( 294 BrowserThread::PostTask(
299 BrowserThread::UI, FROM_HERE, 295 BrowserThread::UI, FROM_HERE,
300 base::Bind(&DownloadManager::UpdateDownload, 296 base::Bind(&content::DownloadDestinationObserver::DestinationUpdate,
301 download_manager_, id_.local(), 297 observer_, BytesSoFar(), CurrentSpeed(), GetHashState()));
302 BytesSoFar(), CurrentSpeed(), GetHashState()));
303 } 298 }
299
300 // static
301 int content::DownloadFile::GetNumberOfDownloadFiles() {
302 return number_active_objects_;
303 }
304
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698