OLD | NEW |
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_manager_impl.h" | 5 #include "content/browser/download/download_manager_impl.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/debug/alias.h" | 11 #include "base/debug/alias.h" |
12 #include "base/i18n/case_conversion.h" | 12 #include "base/i18n/case_conversion.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
18 #include "base/supports_user_data.h" | 18 #include "base/supports_user_data.h" |
19 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
21 #include "content/browser/byte_stream.h" | 21 #include "content/browser/byte_stream.h" |
22 #include "content/browser/download/download_create_info.h" | 22 #include "content/browser/download/download_create_info.h" |
23 #include "content/browser/download/download_file_factory.h" | 23 #include "content/browser/download/download_file_factory.h" |
24 #include "content/browser/download/download_item_factory.h" | 24 #include "content/browser/download/download_item_factory.h" |
25 #include "content/browser/download/download_item_impl.h" | 25 #include "content/browser/download/download_item_impl.h" |
26 #include "content/browser/download/download_stats.h" | 26 #include "content/browser/download/download_stats.h" |
| 27 #include "content/browser/download/url_downloader.h" |
27 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 28 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
28 #include "content/browser/renderer_host/render_view_host_impl.h" | 29 #include "content/browser/renderer_host/render_view_host_impl.h" |
29 #include "content/browser/web_contents/web_contents_impl.h" | 30 #include "content/browser/web_contents/web_contents_impl.h" |
30 #include "content/public/browser/browser_context.h" | 31 #include "content/public/browser/browser_context.h" |
31 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
33 #include "content/public/browser/download_interrupt_reasons.h" | 34 #include "content/public/browser/download_interrupt_reasons.h" |
34 #include "content/public/browser/download_manager_delegate.h" | 35 #include "content/public/browser/download_manager_delegate.h" |
35 #include "content/public/browser/download_url_parameters.h" | 36 #include "content/public/browser/download_url_parameters.h" |
36 #include "content/public/browser/notification_service.h" | 37 #include "content/public/browser/notification_service.h" |
37 #include "content/public/browser/notification_types.h" | 38 #include "content/public/browser/notification_types.h" |
38 #include "content/public/browser/render_process_host.h" | 39 #include "content/public/browser/render_process_host.h" |
39 #include "content/public/browser/resource_context.h" | 40 #include "content/public/browser/resource_context.h" |
40 #include "content/public/browser/web_contents_delegate.h" | 41 #include "content/public/browser/web_contents_delegate.h" |
41 #include "content/public/common/referrer.h" | 42 #include "content/public/common/referrer.h" |
42 #include "net/base/load_flags.h" | 43 #include "net/base/load_flags.h" |
43 #include "net/base/upload_bytes_element_reader.h" | 44 #include "net/base/upload_bytes_element_reader.h" |
44 #include "net/base/upload_data_stream.h" | 45 #include "net/base/upload_data_stream.h" |
45 #include "net/url_request/url_request_context.h" | 46 #include "net/url_request/url_request_context.h" |
46 | 47 |
47 namespace content { | 48 namespace content { |
48 namespace { | 49 namespace { |
49 | 50 |
50 void BeginDownload(scoped_ptr<DownloadUrlParameters> params, | |
51 uint32 download_id) { | |
52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
53 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and | |
54 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so | |
55 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. | |
56 scoped_ptr<net::URLRequest> request( | |
57 params->resource_context()->GetRequestContext()->CreateRequest( | |
58 params->url(), NULL)); | |
59 request->set_load_flags(request->load_flags() | params->load_flags()); | |
60 request->set_method(params->method()); | |
61 if (!params->post_body().empty()) { | |
62 const std::string& body = params->post_body(); | |
63 scoped_ptr<net::UploadElementReader> reader( | |
64 net::UploadOwnedBytesElementReader::CreateWithString(body)); | |
65 request->set_upload(make_scoped_ptr( | |
66 net::UploadDataStream::CreateWithReader(reader.Pass(), 0))); | |
67 } | |
68 if (params->post_id() >= 0) { | |
69 // The POST in this case does not have an actual body, and only works | |
70 // when retrieving data from cache. This is done because we don't want | |
71 // to do a re-POST without user consent, and currently don't have a good | |
72 // plan on how to display the UI for that. | |
73 DCHECK(params->prefer_cache()); | |
74 DCHECK(params->method() == "POST"); | |
75 ScopedVector<net::UploadElementReader> element_readers; | |
76 request->set_upload(make_scoped_ptr( | |
77 new net::UploadDataStream(&element_readers, params->post_id()))); | |
78 } | |
79 | |
80 // If we're not at the beginning of the file, retrieve only the remaining | |
81 // portion. | |
82 bool has_last_modified = !params->last_modified().empty(); | |
83 bool has_etag = !params->etag().empty(); | |
84 | |
85 // If we've asked for a range, we want to make sure that we only | |
86 // get that range if our current copy of the information is good. | |
87 // We shouldn't be asked to continue if we don't have a verifier. | |
88 DCHECK(params->offset() == 0 || has_etag || has_last_modified); | |
89 | |
90 if (params->offset() > 0) { | |
91 request->SetExtraRequestHeaderByName( | |
92 "Range", | |
93 base::StringPrintf("bytes=%" PRId64 "-", params->offset()), | |
94 true); | |
95 | |
96 if (has_last_modified) { | |
97 request->SetExtraRequestHeaderByName("If-Unmodified-Since", | |
98 params->last_modified(), | |
99 true); | |
100 } | |
101 if (has_etag) { | |
102 request->SetExtraRequestHeaderByName("If-Match", params->etag(), true); | |
103 } | |
104 } | |
105 | |
106 for (DownloadUrlParameters::RequestHeadersType::const_iterator iter | |
107 = params->request_headers_begin(); | |
108 iter != params->request_headers_end(); | |
109 ++iter) { | |
110 request->SetExtraRequestHeaderByName( | |
111 iter->first, iter->second, false/*overwrite*/); | |
112 } | |
113 | |
114 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); | |
115 save_info->file_path = params->file_path(); | |
116 save_info->suggested_name = params->suggested_name(); | |
117 save_info->offset = params->offset(); | |
118 save_info->hash_state = params->hash_state(); | |
119 save_info->prompt_for_save_location = params->prompt(); | |
120 save_info->file_stream = params->GetFileStream(); | |
121 | |
122 ResourceDispatcherHost::Get()->BeginDownload( | |
123 request.Pass(), | |
124 params->referrer(), | |
125 params->content_initiated(), | |
126 params->resource_context(), | |
127 params->render_process_host_id(), | |
128 params->render_view_host_routing_id(), | |
129 params->prefer_cache(), | |
130 save_info.Pass(), | |
131 download_id, | |
132 params->callback()); | |
133 } | |
134 | |
135 class MapValueIteratorAdapter { | 51 class MapValueIteratorAdapter { |
136 public: | 52 public: |
137 explicit MapValueIteratorAdapter( | 53 explicit MapValueIteratorAdapter( |
138 base::hash_map<int64, DownloadItem*>::const_iterator iter) | 54 base::hash_map<int64, DownloadItem*>::const_iterator iter) |
139 : iter_(iter) { | 55 : iter_(iter) { |
140 } | 56 } |
141 ~MapValueIteratorAdapter() {} | 57 ~MapValueIteratorAdapter() {} |
142 | 58 |
143 DownloadItem* operator*() { return iter_->second; } | 59 DownloadItem* operator*() { return iter_->second; } |
144 | 60 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 bound_net_log); | 122 bound_net_log); |
207 } | 123 } |
208 | 124 |
209 virtual DownloadItemImpl* CreateActiveItem( | 125 virtual DownloadItemImpl* CreateActiveItem( |
210 DownloadItemImplDelegate* delegate, | 126 DownloadItemImplDelegate* delegate, |
211 uint32 download_id, | 127 uint32 download_id, |
212 const DownloadCreateInfo& info, | 128 const DownloadCreateInfo& info, |
213 const net::BoundNetLog& bound_net_log) OVERRIDE { | 129 const net::BoundNetLog& bound_net_log) OVERRIDE { |
214 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); | 130 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); |
215 } | 131 } |
216 | |
217 virtual DownloadItemImpl* CreateSavePageItem( | |
218 DownloadItemImplDelegate* delegate, | |
219 uint32 download_id, | |
220 const base::FilePath& path, | |
221 const GURL& url, | |
222 const std::string& mime_type, | |
223 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
224 const net::BoundNetLog& bound_net_log) OVERRIDE { | |
225 return new DownloadItemImpl(delegate, download_id, path, url, | |
226 mime_type, request_handle.Pass(), | |
227 bound_net_log); | |
228 } | |
229 }; | 132 }; |
230 | 133 |
231 } // namespace | 134 } // namespace |
232 | 135 |
233 DownloadManagerImpl::DownloadManagerImpl( | 136 DownloadManagerImpl::DownloadManagerImpl( |
234 net::NetLog* net_log, | 137 net::NetLog* net_log, |
235 BrowserContext* browser_context) | 138 BrowserContext* browser_context) |
236 : item_factory_(new DownloadItemFactoryImpl()), | 139 : item_factory_(new DownloadItemFactoryImpl()), |
237 file_factory_(new DownloadFileFactory()), | 140 file_factory_(new DownloadFileFactory()), |
238 history_size_(0), | 141 history_size_(0), |
239 shutdown_needed_(true), | 142 shutdown_needed_(true), |
240 browser_context_(browser_context), | 143 browser_context_(browser_context), |
241 delegate_(NULL), | 144 delegate_(NULL), |
242 net_log_(net_log), | 145 net_log_(net_log), |
243 weak_factory_(this) { | 146 weak_factory_(this) { |
244 DCHECK(browser_context); | 147 DCHECK(browser_context); |
245 } | 148 } |
246 | 149 |
247 DownloadManagerImpl::~DownloadManagerImpl() { | 150 DownloadManagerImpl::~DownloadManagerImpl() { |
248 DCHECK(!shutdown_needed_); | 151 DCHECK(!shutdown_needed_); |
249 } | 152 } |
250 | 153 |
251 DownloadItemImpl* DownloadManagerImpl::CreateActiveItem( | 154 DownloadItemImpl* DownloadManagerImpl::CreateActiveItem( |
252 uint32 id, const DownloadCreateInfo& info) { | 155 uint32 id, |
| 156 const DownloadCreateInfo& info) { |
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
254 DCHECK(!ContainsKey(downloads_, id)); | 158 DCHECK(!ContainsKey(downloads_, id)); |
255 net::BoundNetLog bound_net_log = | 159 net::BoundNetLog bound_net_log = |
256 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 160 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
257 DownloadItemImpl* download = | 161 DownloadItemImpl* download = |
258 item_factory_->CreateActiveItem(this, id, info, bound_net_log); | 162 item_factory_->CreateActiveItem(this, id, info, bound_net_log); |
259 downloads_[id] = download; | 163 downloads_[id] = download; |
260 return download; | 164 return download; |
261 } | 165 } |
262 | 166 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 downloads_.clear(); | 253 downloads_.clear(); |
350 | 254 |
351 // We'll have nothing more to report to the observers after this point. | 255 // We'll have nothing more to report to the observers after this point. |
352 observers_.Clear(); | 256 observers_.Clear(); |
353 | 257 |
354 if (delegate_) | 258 if (delegate_) |
355 delegate_->Shutdown(); | 259 delegate_->Shutdown(); |
356 delegate_ = NULL; | 260 delegate_ = NULL; |
357 } | 261 } |
358 | 262 |
359 void DownloadManagerImpl::StartDownload( | 263 void DownloadManagerImpl::StartDownloadWithActiveRequest( |
360 scoped_ptr<DownloadCreateInfo> info, | 264 scoped_ptr<DownloadRequestHandle> request_handle, |
361 scoped_ptr<ByteStreamReader> stream, | 265 scoped_ptr<DownloadCreateInfo> info) { |
362 const DownloadUrlParameters::OnStartedCallback& on_started) { | |
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
364 DCHECK(info); | 267 DCHECK(info); |
365 uint32 download_id = info->download_id; | 268 GetNextId(base::Bind(&DownloadManagerImpl::StartDownloadWithId, |
366 const bool new_download = (download_id == content::DownloadItem::kInvalidId); | 269 weak_factory_.GetWeakPtr(), |
367 base::Callback<void(uint32)> got_id(base::Bind( | 270 base::Passed(&request_handle), |
368 &DownloadManagerImpl::StartDownloadWithId, | 271 base::Passed(&info))); |
369 weak_factory_.GetWeakPtr(), | |
370 base::Passed(info.Pass()), | |
371 base::Passed(stream.Pass()), | |
372 on_started, | |
373 new_download)); | |
374 if (new_download) { | |
375 GetNextId(got_id); | |
376 } else { | |
377 got_id.Run(download_id); | |
378 } | |
379 } | 272 } |
380 | 273 |
381 void DownloadManagerImpl::StartDownloadWithId( | 274 void DownloadManagerImpl::StartDownloadWithId( |
| 275 scoped_ptr<DownloadRequestHandle> request_handle, |
382 scoped_ptr<DownloadCreateInfo> info, | 276 scoped_ptr<DownloadCreateInfo> info, |
383 scoped_ptr<ByteStreamReader> stream, | |
384 const DownloadUrlParameters::OnStartedCallback& on_started, | |
385 bool new_download, | |
386 uint32 id) { | 277 uint32 id) { |
387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
388 DCHECK_NE(content::DownloadItem::kInvalidId, id); | 279 pending_requests_.push_back(request_handle.release()); |
389 DownloadItemImpl* download = NULL; | 280 OnDownloadRequestStarted(id, |
390 if (new_download) { | 281 true /* new download */, |
391 download = CreateActiveItem(id, *info); | 282 DownloadUrlParameters::OnStartedCallback(), |
392 } else { | 283 pending_requests_.back(), |
393 DownloadMap::iterator item_iterator = downloads_.find(id); | 284 DOWNLOAD_INTERRUPT_REASON_NONE, |
394 // Trying to resume an interrupted download. | 285 info.Pass()); |
395 if (item_iterator == downloads_.end() || | 286 } |
396 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) { | 287 |
397 // If the download is no longer known to the DownloadManager, then it was | 288 DownloadItemImpl* DownloadManagerImpl::UpdateAndGetResumedDownloadItem( |
398 // removed after it was resumed. Ignore. If the download is cancelled | 289 uint32 download_id, |
399 // while resuming, then also ignore the request. | 290 DownloadRequestHandle* request_handle, |
400 info->request_handle.CancelRequest(); | 291 const DownloadCreateInfo& new_create_info) { |
401 if (!on_started.is_null()) | 292 DownloadMap::iterator item_iterator = downloads_.find(download_id); |
402 on_started.Run(NULL, net::ERR_ABORTED); | 293 // Trying to resume an interrupted download. |
403 return; | 294 if (item_iterator == downloads_.end() || |
404 } | 295 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) { |
405 download = item_iterator->second; | 296 // If the download is no longer known to the DownloadManager, then it was |
406 DCHECK_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 297 // removed after it was resumed. Ignore. If the download is cancelled |
| 298 // while resuming, then also ignore the request. |
| 299 request_handle->CancelRequest(); |
| 300 return NULL; |
| 301 } |
| 302 DownloadItemImpl* download = item_iterator->second; |
| 303 DCHECK_EQ(DownloadItem::INTERRUPTED, download->GetState()); |
| 304 download->MergeOriginInfoOnResume(new_create_info); |
| 305 return download; |
| 306 } |
| 307 |
| 308 void DownloadManagerImpl::OnDownloadRequestStarted( |
| 309 uint32 download_id, |
| 310 bool new_download, |
| 311 const DownloadUrlParameters::OnStartedCallback& on_started, |
| 312 DownloadRequestHandle* request_handle, |
| 313 DownloadInterruptReason interrupt_reason, |
| 314 scoped_ptr<DownloadCreateInfo> info) { |
| 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 316 DCHECK_NE(content::DownloadItem::kInvalidId, download_id); |
| 317 DCHECK(info); |
| 318 ScopedVector<DownloadRequestHandle>::iterator handle_iter = std::find( |
| 319 pending_requests_.begin(), pending_requests_.end(), request_handle); |
| 320 DCHECK(pending_requests_.end() != handle_iter); |
| 321 pending_requests_.weak_erase(handle_iter); |
| 322 scoped_ptr<DownloadRequestHandle> owned_request_handle(request_handle); |
| 323 DownloadItemImpl* download = |
| 324 new_download |
| 325 ? CreateActiveItem(download_id, *info) |
| 326 : UpdateAndGetResumedDownloadItem(download_id, request_handle, *info); |
| 327 if (!download) { |
| 328 if (!on_started.is_null()) |
| 329 on_started.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
| 330 return; |
407 } | 331 } |
408 | 332 |
409 base::FilePath default_download_directory; | 333 base::FilePath default_download_directory; |
410 if (delegate_) { | 334 if (delegate_) { |
411 base::FilePath website_save_directory; // Unused | 335 base::FilePath website_save_directory; // Unused |
412 bool skip_dir_check = false; // Unused | 336 bool skip_dir_check = false; // Unused |
413 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, | 337 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, |
414 &default_download_directory, &skip_dir_check); | 338 &default_download_directory, &skip_dir_check); |
415 } | 339 } |
416 | 340 |
417 // Create the download file and start the download. | 341 // Create the download file and start the download. |
418 scoped_ptr<DownloadFile> download_file( | 342 scoped_ptr<DownloadFile> download_file( |
419 file_factory_->CreateFile( | 343 file_factory_->CreateFile(info->save_info.Pass(), |
420 info->save_info.Pass(), default_download_directory, | 344 default_download_directory, |
421 info->url(), info->referrer_url, | 345 info->url(), |
422 delegate_->GenerateFileHash(), | 346 info->referrer_url, |
423 stream.Pass(), download->GetBoundNetLog(), | 347 delegate_->GenerateFileHash(), |
424 download->DestinationObserverAsWeakPtr())); | 348 info->stream_reader.Pass(), |
| 349 download->GetBoundNetLog(), |
| 350 download->DestinationObserverAsWeakPtr())); |
425 | 351 |
426 // Attach the client ID identifying the app to the AV system. | 352 // Attach the client ID identifying the app to the AV system. |
427 if (download_file.get() && delegate_) { | 353 if (download_file.get() && delegate_) { |
428 download_file->SetClientGuid( | 354 download_file->SetClientGuid( |
429 delegate_->ApplicationClientIdForFileScanning()); | 355 delegate_->ApplicationClientIdForFileScanning()); |
430 } | 356 } |
431 | 357 |
432 scoped_ptr<DownloadRequestHandleInterface> req_handle( | 358 download->Start(download_file.Pass(), owned_request_handle.Pass()); |
433 new DownloadRequestHandle(info->request_handle)); | |
434 download->Start(download_file.Pass(), req_handle.Pass()); | |
435 | 359 |
436 // For interrupted downloads, Start() will transition the state to | 360 // For interrupted downloads, Start() will transition the state to |
437 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated(). | 361 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated(). |
438 // For new downloads, we notify here, rather than earlier, so that | 362 // For new downloads, we notify here, rather than earlier, so that |
439 // the download_file is bound to download and all the usual | 363 // the download_file is bound to download and all the usual |
440 // setters (e.g. Cancel) work. | 364 // setters (e.g. Cancel) work. |
441 if (new_download) | 365 if (new_download) |
442 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 366 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
443 | 367 |
444 if (!on_started.is_null()) | 368 if (!on_started.is_null()) |
445 on_started.Run(download, net::OK); | 369 on_started.Run(download, DOWNLOAD_INTERRUPT_REASON_NONE); |
446 } | 370 } |
447 | 371 |
448 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { | 372 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { |
449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
450 for (DownloadMap::iterator it = downloads_.begin(); | 374 for (DownloadMap::iterator it = downloads_.begin(); |
451 it != downloads_.end(); ++it) { | 375 it != downloads_.end(); ++it) { |
452 DownloadItemImpl* item = it->second; | 376 DownloadItemImpl* item = it->second; |
453 CheckForFileRemoval(item); | 377 CheckForFileRemoval(item); |
454 } | 378 } |
455 } | 379 } |
456 | 380 |
457 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { | 381 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { |
458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
459 if ((download_item->GetState() == DownloadItem::COMPLETE) && | 383 if ((download_item->GetState() == DownloadItem::COMPLETE) && |
460 !download_item->GetFileExternallyRemoved() && | 384 !download_item->GetFileExternallyRemoved() && |
461 delegate_) { | 385 delegate_) { |
462 delegate_->CheckForFileExistence( | 386 delegate_->CheckForFileExistence( |
463 download_item, | 387 download_item, |
464 base::Bind(&DownloadManagerImpl::OnFileExistenceChecked, | 388 base::Bind(&DownloadManagerImpl::OnFileExistenceChecked, |
465 weak_factory_.GetWeakPtr(), download_item->GetId())); | 389 weak_factory_.GetWeakPtr(), download_item->GetId())); |
466 } | 390 } |
467 } | 391 } |
468 | 392 |
| 393 void DownloadManagerImpl::DownloadUrlWithId( |
| 394 scoped_ptr<DownloadUrlParameters> params, |
| 395 bool new_download, |
| 396 uint32 download_id) { |
| 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 398 DCHECK_NE(DownloadItem::kInvalidId, download_id); |
| 399 DownloadUrlParameters::OnStartedCallback on_started_callback = |
| 400 params->callback(); |
| 401 scoped_ptr<DownloadRequestHandle> request_handle( |
| 402 UrlDownloader::CreateDownloadRequest(params.Pass())); |
| 403 pending_requests_.push_back(request_handle.release()); |
| 404 DownloadRequestHandle::RequestStartedCallback started_callback = |
| 405 base::Bind(&DownloadManagerImpl::OnDownloadRequestStarted, |
| 406 weak_factory_.GetWeakPtr(), |
| 407 download_id, |
| 408 new_download, |
| 409 on_started_callback, |
| 410 pending_requests_.back()); |
| 411 pending_requests_.back()->Start(started_callback); |
| 412 } |
| 413 |
469 void DownloadManagerImpl::OnFileExistenceChecked(uint32 download_id, | 414 void DownloadManagerImpl::OnFileExistenceChecked(uint32 download_id, |
470 bool result) { | 415 bool result) { |
471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
472 if (!result) { // File does not exist. | 417 if (!result) { // File does not exist. |
473 if (ContainsKey(downloads_, download_id)) | 418 if (ContainsKey(downloads_, download_id)) |
474 downloads_[download_id]->OnDownloadedFileRemoved(); | 419 downloads_[download_id]->OnDownloadedFileRemoved(); |
475 } | 420 } |
476 } | 421 } |
477 | 422 |
478 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 423 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
479 return browser_context_; | 424 return browser_context_; |
480 } | 425 } |
481 | 426 |
482 void DownloadManagerImpl::CreateSavePackageDownloadItem( | 427 void DownloadManagerImpl::CreateSavePackageDownloadItem( |
483 const base::FilePath& main_file_path, | 428 scoped_ptr<DownloadCreateInfo> create_info, |
484 const GURL& page_url, | 429 const DownloadItemImplCreated& download_created_callback) { |
485 const std::string& mime_type, | |
486 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
487 const DownloadItemImplCreated& item_created) { | |
488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
489 GetNextId(base::Bind( | 431 DCHECK(create_info->is_save_package_download); |
490 &DownloadManagerImpl::CreateSavePackageDownloadItemWithId, | 432 |
491 weak_factory_.GetWeakPtr(), | 433 GetNextId( |
492 main_file_path, | 434 base::Bind(&DownloadManagerImpl::CreateSavePackageDownloadItemWithId, |
493 page_url, | 435 weak_factory_.GetWeakPtr(), |
494 mime_type, | 436 base::Passed(&create_info), |
495 base::Passed(request_handle.Pass()), | 437 download_created_callback)); |
496 item_created)); | |
497 } | 438 } |
498 | 439 |
499 void DownloadManagerImpl::CreateSavePackageDownloadItemWithId( | 440 void DownloadManagerImpl::CreateSavePackageDownloadItemWithId( |
500 const base::FilePath& main_file_path, | 441 scoped_ptr<DownloadCreateInfo> create_info, |
501 const GURL& page_url, | 442 const DownloadItemImplCreated& download_created_callback, |
502 const std::string& mime_type, | |
503 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
504 const DownloadItemImplCreated& item_created, | |
505 uint32 id) { | 443 uint32 id) { |
506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
507 DCHECK_NE(content::DownloadItem::kInvalidId, id); | 445 DownloadItemImpl* item = CreateActiveItem(id, *create_info); |
508 DCHECK(!ContainsKey(downloads_, id)); | 446 download_created_callback.Run(item); |
509 net::BoundNetLog bound_net_log = | |
510 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
511 DownloadItemImpl* download_item = item_factory_->CreateSavePageItem( | |
512 this, | |
513 id, | |
514 main_file_path, | |
515 page_url, | |
516 mime_type, | |
517 request_handle.Pass(), | |
518 bound_net_log); | |
519 downloads_[download_item->GetId()] = download_item; | |
520 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated( | |
521 this, download_item)); | |
522 if (!item_created.is_null()) | |
523 item_created.Run(download_item); | |
524 } | 447 } |
525 | 448 |
526 void DownloadManagerImpl::OnSavePackageSuccessfullyFinished( | 449 void DownloadManagerImpl::OnSavePackageSuccessfullyFinished( |
527 DownloadItem* download_item) { | 450 DownloadItem* download_item) { |
528 FOR_EACH_OBSERVER(Observer, observers_, | 451 FOR_EACH_OBSERVER(Observer, observers_, |
529 OnSavePackageSuccessfullyFinished(this, download_item)); | 452 OnSavePackageSuccessfullyFinished(this, download_item)); |
530 } | 453 } |
531 | 454 |
532 // Resume a download of a specific URL. We send the request to the | 455 // Resume a download of a specific URL. We send the request to the |
533 // ResourceDispatcherHost, and let it send us responses like a regular | 456 // ResourceDispatcherHost, and let it send us responses like a regular |
534 // download. | 457 // download. |
535 void DownloadManagerImpl::ResumeInterruptedDownload( | 458 void DownloadManagerImpl::ResumeInterruptedDownload( |
536 scoped_ptr<content::DownloadUrlParameters> params, | 459 scoped_ptr<content::DownloadUrlParameters> params, |
537 uint32 id) { | 460 uint32 id) { |
538 RecordDownloadSource(INITIATED_BY_RESUMPTION); | 461 RecordDownloadSource(INITIATED_BY_RESUMPTION); |
539 BrowserThread::PostTask( | 462 DownloadUrlWithId(params.Pass(), false /* new_download */, id); |
540 BrowserThread::IO, | |
541 FROM_HERE, | |
542 base::Bind(&BeginDownload, base::Passed(¶ms), id)); | |
543 } | 463 } |
544 | 464 |
545 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( | 465 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( |
546 scoped_ptr<DownloadItemFactory> item_factory) { | 466 scoped_ptr<DownloadItemFactory> item_factory) { |
547 item_factory_ = item_factory.Pass(); | 467 item_factory_ = item_factory.Pass(); |
548 } | 468 } |
549 | 469 |
550 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( | 470 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( |
551 scoped_ptr<DownloadFileFactory> file_factory) { | 471 scoped_ptr<DownloadFileFactory> file_factory) { |
552 file_factory_ = file_factory.Pass(); | 472 file_factory_ = file_factory.Pass(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 return num_deleted; | 520 return num_deleted; |
601 } | 521 } |
602 | 522 |
603 void DownloadManagerImpl::DownloadUrl( | 523 void DownloadManagerImpl::DownloadUrl( |
604 scoped_ptr<DownloadUrlParameters> params) { | 524 scoped_ptr<DownloadUrlParameters> params) { |
605 if (params->post_id() >= 0) { | 525 if (params->post_id() >= 0) { |
606 // Check this here so that the traceback is more useful. | 526 // Check this here so that the traceback is more useful. |
607 DCHECK(params->prefer_cache()); | 527 DCHECK(params->prefer_cache()); |
608 DCHECK(params->method() == "POST"); | 528 DCHECK(params->method() == "POST"); |
609 } | 529 } |
610 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 530 |
611 &BeginDownload, base::Passed(¶ms), | 531 GetNextId(base::Bind(&DownloadManagerImpl::DownloadUrlWithId, |
612 content::DownloadItem::kInvalidId)); | 532 weak_factory_.GetWeakPtr(), |
| 533 base::Passed(¶ms), |
| 534 true /* new_download */)); |
613 } | 535 } |
614 | 536 |
615 void DownloadManagerImpl::AddObserver(Observer* observer) { | 537 void DownloadManagerImpl::AddObserver(Observer* observer) { |
616 observers_.AddObserver(observer); | 538 observers_.AddObserver(observer); |
617 } | 539 } |
618 | 540 |
619 void DownloadManagerImpl::RemoveObserver(Observer* observer) { | 541 void DownloadManagerImpl::RemoveObserver(Observer* observer) { |
620 observers_.RemoveObserver(observer); | 542 observers_.RemoveObserver(observer); |
621 } | 543 } |
622 | 544 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 if (delegate_) | 620 if (delegate_) |
699 delegate_->OpenDownload(download); | 621 delegate_->OpenDownload(download); |
700 } | 622 } |
701 | 623 |
702 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) { | 624 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) { |
703 if (delegate_) | 625 if (delegate_) |
704 delegate_->ShowDownloadInShell(download); | 626 delegate_->ShowDownloadInShell(download); |
705 } | 627 } |
706 | 628 |
707 } // namespace content | 629 } // namespace content |
OLD | NEW |