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/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/i18n/case_conversion.h" | 13 #include "base/i18n/case_conversion.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.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 "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
21 #include "build/build_config.h" | 21 #include "build/build_config.h" |
22 #include "content/browser/download/byte_stream.h" | 22 #include "content/browser/download/byte_stream.h" |
23 #include "content/browser/download/download_create_info.h" | 23 #include "content/browser/download/download_create_info.h" |
24 #include "content/browser/download/download_file_manager.h" | 24 #include "content/browser/download/download_file_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/renderer_host/render_view_host_impl.h" | 27 #include "content/browser/renderer_host/render_view_host_impl.h" |
28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
29 #include "content/browser/web_contents/web_contents_impl.h" | 29 #include "content/browser/web_contents/web_contents_impl.h" |
30 #include "content/public/browser/browser_context.h" | 30 #include "content/public/browser/browser_context.h" |
31 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/content_browser_client.h" | 32 #include "content/public/browser/content_browser_client.h" |
33 #include "content/public/browser/download_interrupt_reasons.h" | 33 #include "content/public/browser/download_interrupt_reasons.h" |
34 #include "content/public/browser/download_manager_delegate.h" | 34 #include "content/public/browser/download_manager_delegate.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 | 137 |
138 bool operator!=(const MapValueIteratorAdapter& that) const { | 138 bool operator!=(const MapValueIteratorAdapter& that) const { |
139 return iter_ != that.iter_; | 139 return iter_ != that.iter_; |
140 } | 140 } |
141 | 141 |
142 private: | 142 private: |
143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; | 143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; |
144 // Allow copy and assign. | 144 // Allow copy and assign. |
145 }; | 145 }; |
146 | 146 |
147 void EnsureNoPendingDownloadsOnFile(scoped_refptr<DownloadFileManager> dfm, | 147 void EnsureNoPendingDownloadJobsOnFile(bool* result) { |
148 bool* result) { | 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
149 if (dfm->NumberOfActiveDownloads()) | 149 *result = (content::DownloadFile::GetNumberOfDownloadFiles() == 0); |
150 *result = false; | |
151 BrowserThread::PostTask( | 150 BrowserThread::PostTask( |
152 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 151 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
153 } | 152 } |
154 | 153 |
155 void EnsureNoPendingDownloadJobsOnIO(bool* result) { | |
156 scoped_refptr<DownloadFileManager> download_file_manager = | |
157 ResourceDispatcherHostImpl::Get()->download_file_manager(); | |
158 BrowserThread::PostTask( | |
159 BrowserThread::FILE, FROM_HERE, | |
160 base::Bind(&EnsureNoPendingDownloadsOnFile, | |
161 download_file_manager, result)); | |
162 } | |
163 | |
164 class DownloadItemFactoryImpl : public content::DownloadItemFactory { | 154 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
165 public: | 155 public: |
166 DownloadItemFactoryImpl() {} | 156 DownloadItemFactoryImpl() {} |
167 virtual ~DownloadItemFactoryImpl() {} | 157 virtual ~DownloadItemFactoryImpl() {} |
168 | 158 |
169 virtual DownloadItemImpl* CreatePersistedItem( | 159 virtual DownloadItemImpl* CreatePersistedItem( |
170 DownloadItemImplDelegate* delegate, | 160 DownloadItemImplDelegate* delegate, |
171 content::DownloadId download_id, | 161 content::DownloadId download_id, |
172 const content::DownloadPersistentStoreInfo& info, | 162 const content::DownloadPersistentStoreInfo& info, |
173 const net::BoundNetLog& bound_net_log) OVERRIDE { | 163 const net::BoundNetLog& bound_net_log) OVERRIDE { |
(...skipping 24 matching lines...) Expand all Loading... |
198 }; | 188 }; |
199 | 189 |
200 } // namespace | 190 } // namespace |
201 | 191 |
202 namespace content { | 192 namespace content { |
203 | 193 |
204 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 194 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
206 bool result = true; | 196 bool result = true; |
207 BrowserThread::PostTask( | 197 BrowserThread::PostTask( |
208 BrowserThread::IO, FROM_HERE, | 198 BrowserThread::FILE, FROM_HERE, |
209 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); | 199 base::Bind(&EnsureNoPendingDownloadJobsOnFile, &result)); |
210 MessageLoop::current()->Run(); | 200 MessageLoop::current()->Run(); |
211 return result; | 201 return result; |
212 } | 202 } |
213 | 203 |
214 } // namespace content | 204 } // namespace content |
215 | 205 |
216 DownloadManagerImpl::DownloadManagerImpl( | 206 DownloadManagerImpl::DownloadManagerImpl( |
217 DownloadFileManager* file_manager, | 207 scoped_ptr<content::DownloadItemFactory> item_factory, |
218 scoped_ptr<content::DownloadItemFactory> factory, | |
219 net::NetLog* net_log) | 208 net::NetLog* net_log) |
220 : factory_(factory.Pass()), | 209 : item_factory_(item_factory.Pass()), |
221 history_size_(0), | 210 history_size_(0), |
222 shutdown_needed_(false), | 211 shutdown_needed_(false), |
223 browser_context_(NULL), | 212 browser_context_(NULL), |
224 file_manager_(file_manager), | |
225 delegate_(NULL), | 213 delegate_(NULL), |
226 net_log_(net_log) { | 214 net_log_(net_log) { |
227 DCHECK(file_manager); | 215 if (!item_factory_.get()) |
228 if (!factory_.get()) | 216 item_factory_.reset(new DownloadItemFactoryImpl()); |
229 factory_.reset(new DownloadItemFactoryImpl()); | 217 file_factory_.reset(new content::DownloadFileFactory()); |
230 } | 218 } |
231 | 219 |
232 DownloadManagerImpl::~DownloadManagerImpl() { | 220 DownloadManagerImpl::~DownloadManagerImpl() { |
233 DCHECK(!shutdown_needed_); | 221 DCHECK(!shutdown_needed_); |
234 } | 222 } |
235 | 223 |
236 DownloadId DownloadManagerImpl::GetNextId() { | 224 DownloadId DownloadManagerImpl::GetNextId() { |
237 DownloadId id; | 225 DownloadId id; |
238 if (delegate_) | 226 if (delegate_) |
239 id = delegate_->GetNextId(); | 227 id = delegate_->GetNextId(); |
240 if (!id.IsValid()) { | 228 if (!id.IsValid()) { |
241 static int next_id; | 229 static int next_id; |
242 id = DownloadId(browser_context_, ++next_id); | 230 id = DownloadId(browser_context_, ++next_id); |
243 } | 231 } |
244 | 232 |
245 return id; | 233 return id; |
246 } | 234 } |
247 | 235 |
248 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() { | 236 void DownloadManagerImpl::DelegateStart(DownloadItemImpl* item) { |
249 return file_manager_; | 237 content::DownloadTargetCallback callback = |
| 238 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, |
| 239 this, item->GetId()); |
| 240 if (!delegate_ || !delegate_->DetermineDownloadTarget(item, callback)) { |
| 241 FilePath target_path = item->GetForcedFilePath(); |
| 242 // TODO(asanka): Determine a useful path if |target_path| is empty. |
| 243 callback.Run(target_path, |
| 244 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 245 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 246 target_path); |
| 247 } |
250 } | 248 } |
251 | 249 |
252 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { | 250 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { |
253 if (!delegate_) | 251 if (!delegate_) |
254 return true; | 252 return true; |
255 | 253 |
256 return delegate_->ShouldOpenDownload(item); | 254 return delegate_->ShouldOpenDownload(item); |
257 } | 255 } |
258 | 256 |
259 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { | 257 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { |
(...skipping 15 matching lines...) Expand all Loading... |
275 void DownloadManagerImpl::Shutdown() { | 273 void DownloadManagerImpl::Shutdown() { |
276 VLOG(20) << __FUNCTION__ << "()" | 274 VLOG(20) << __FUNCTION__ << "()" |
277 << " shutdown_needed_ = " << shutdown_needed_; | 275 << " shutdown_needed_ = " << shutdown_needed_; |
278 if (!shutdown_needed_) | 276 if (!shutdown_needed_) |
279 return; | 277 return; |
280 shutdown_needed_ = false; | 278 shutdown_needed_ = false; |
281 | 279 |
282 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); | 280 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); |
283 // TODO(benjhayden): Consider clearing observers_. | 281 // TODO(benjhayden): Consider clearing observers_. |
284 | 282 |
285 DCHECK(file_manager_); | 283 // The DownloadFiles will be canceled and deleted by their DownloadItems. |
286 BrowserThread::PostTask( | |
287 BrowserThread::FILE, FROM_HERE, | |
288 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, | |
289 file_manager_, make_scoped_refptr(this))); | |
290 | 284 |
291 AssertContainersConsistent(); | 285 AssertContainersConsistent(); |
292 | 286 |
293 // Go through all downloads in downloads_. Dangerous ones we need to | 287 // Go through all downloads in downloads_. Dangerous ones we need to |
294 // remove on disk, and in progress ones we need to cancel. | 288 // remove on disk, and in progress ones we need to cancel. |
295 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { | 289 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { |
296 DownloadItemImpl* download = it->second; | 290 DownloadItemImpl* download = it->second; |
297 | 291 |
298 // Save iterator from potential erases in this set done by called code. | 292 // Save iterator from potential erases in this set done by called code. |
299 // Iterators after an erasure point are still valid for lists and | 293 // Iterators after an erasure point are still valid for lists and |
(...skipping 22 matching lines...) Expand all Loading... |
322 // and all in progress downloads have been cancelled. We can now delete | 316 // and all in progress downloads have been cancelled. We can now delete |
323 // anything left. | 317 // anything left. |
324 | 318 |
325 active_downloads_.clear(); | 319 active_downloads_.clear(); |
326 STLDeleteValues(&downloads_); | 320 STLDeleteValues(&downloads_); |
327 downloads_.clear(); | 321 downloads_.clear(); |
328 | 322 |
329 // We'll have nothing more to report to the observers after this point. | 323 // We'll have nothing more to report to the observers after this point. |
330 observers_.Clear(); | 324 observers_.Clear(); |
331 | 325 |
332 file_manager_ = NULL; | |
333 if (delegate_) | 326 if (delegate_) |
334 delegate_->Shutdown(); | 327 delegate_->Shutdown(); |
335 delegate_ = NULL; | 328 delegate_ = NULL; |
336 } | 329 } |
337 | 330 |
338 void DownloadManagerImpl::GetTemporaryDownloads( | 331 void DownloadManagerImpl::GetTemporaryDownloads( |
339 const FilePath& dir_path, DownloadVector* result) { | 332 const FilePath& dir_path, DownloadVector* result) { |
340 DCHECK(result); | 333 DCHECK(result); |
341 | 334 |
342 for (DownloadMap::iterator it = downloads_.begin(); | 335 for (DownloadMap::iterator it = downloads_.begin(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 383 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
391 DCHECK(browser_context); | 384 DCHECK(browser_context); |
392 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 385 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
393 shutdown_needed_ = true; | 386 shutdown_needed_ = true; |
394 | 387 |
395 browser_context_ = browser_context; | 388 browser_context_ = browser_context; |
396 | 389 |
397 return true; | 390 return true; |
398 } | 391 } |
399 | 392 |
400 // We have received a message from DownloadFileManager about a new download. | |
401 content::DownloadId DownloadManagerImpl::StartDownload( | 393 content::DownloadId DownloadManagerImpl::StartDownload( |
402 scoped_ptr<DownloadCreateInfo> info, | 394 scoped_ptr<DownloadCreateInfo> info, |
403 scoped_ptr<content::ByteStreamReader> stream) { | 395 scoped_ptr<content::ByteStreamReader> stream) { |
404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
405 | 397 |
406 // |bound_net_log| will be used for logging both the download item's and | 398 net::BoundNetLog bound_net_log = |
407 // the download file's events. | 399 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
408 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get()); | |
409 | 400 |
410 // If info->download_id was unknown on entry to this function, it was | 401 // We create the DownloadItem before the DownloadFile because the |
411 // assigned in CreateDownloadItem. | 402 // DownloadItem already needs to handle a state in which there is |
412 DownloadId download_id = info->download_id; | 403 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) |
| 404 DownloadItemImpl* download = |
| 405 CreateDownloadItem(info.get(), bound_net_log); |
| 406 scoped_ptr<content::DownloadFile> download_file( |
| 407 file_factory_->CreateFile( |
| 408 info->save_info, info->url(), info->referrer_url, |
| 409 info->received_bytes, GenerateFileHash(), |
| 410 stream.Pass(), bound_net_log, |
| 411 download->DestinationObserverAsWeakPtr())); |
| 412 download->Start(download_file.Pass()); |
413 | 413 |
414 DownloadFileManager::CreateDownloadFileCallback callback( | 414 return download->GetGlobalId(); |
415 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated, | |
416 this, download_id.local())); | |
417 | |
418 BrowserThread::PostTask( | |
419 BrowserThread::FILE, FROM_HERE, | |
420 base::Bind(&DownloadFileManager::CreateDownloadFile, | |
421 file_manager_, base::Passed(info.Pass()), | |
422 base::Passed(stream.Pass()), | |
423 make_scoped_refptr(this), | |
424 GenerateFileHash(), bound_net_log, | |
425 callback)); | |
426 | |
427 return download_id; | |
428 } | |
429 | |
430 void DownloadManagerImpl::OnDownloadFileCreated( | |
431 int32 download_id, content::DownloadInterruptReason reason) { | |
432 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | |
433 OnDownloadInterrupted(download_id, reason); | |
434 // TODO(rdsmith): It makes no sense to continue along the | |
435 // regular download path after we've gotten an error. But it's | |
436 // the way the code has historically worked, and this allows us | |
437 // to get the download persisted and observers of the download manager | |
438 // notified, so tests work. When we execute all side effects of cancel | |
439 // (including queue removal) immedately rather than waiting for | |
440 // persistence we should replace this comment with a "return;". | |
441 } | |
442 | |
443 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | |
444 if (download_iter == active_downloads_.end()) | |
445 return; | |
446 | |
447 DownloadItemImpl* download = download_iter->second; | |
448 content::DownloadTargetCallback callback = | |
449 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, | |
450 this, download_id); | |
451 if (!delegate_ || !delegate_->DetermineDownloadTarget(download, callback)) { | |
452 FilePath target_path = download->GetForcedFilePath(); | |
453 // TODO(asanka): Determine a useful path if |target_path| is empty. | |
454 callback.Run(target_path, | |
455 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
456 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
457 target_path); | |
458 } | |
459 } | 415 } |
460 | 416 |
461 void DownloadManagerImpl::OnDownloadTargetDetermined( | 417 void DownloadManagerImpl::OnDownloadTargetDetermined( |
462 int32 download_id, | 418 int32 download_id, |
463 const FilePath& target_path, | 419 const FilePath& target_path, |
464 DownloadItem::TargetDisposition disposition, | 420 DownloadItem::TargetDisposition disposition, |
465 content::DownloadDangerType danger_type, | 421 content::DownloadDangerType danger_type, |
466 const FilePath& intermediate_path) { | 422 const FilePath& intermediate_path) { |
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
468 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 424 DownloadMap::iterator download_iter = active_downloads_.find(download_id); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { | 468 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { |
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
514 if (ContainsKey(downloads_, download_id)) | 470 if (ContainsKey(downloads_, download_id)) |
515 downloads_[download_id]->OnDownloadedFileRemoved(); | 471 downloads_[download_id]->OnDownloadedFileRemoved(); |
516 } | 472 } |
517 | 473 |
518 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 474 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
519 return browser_context_; | 475 return browser_context_; |
520 } | 476 } |
521 | 477 |
522 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( | 478 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( |
523 DownloadCreateInfo* info) { | 479 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { |
524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
525 | 481 |
526 net::BoundNetLog bound_net_log = | |
527 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
528 if (!info->download_id.IsValid()) | 482 if (!info->download_id.IsValid()) |
529 info->download_id = GetNextId(); | 483 info->download_id = GetNextId(); |
530 DownloadItemImpl* download = factory_->CreateActiveItem( | 484 DownloadItemImpl* download = item_factory_->CreateActiveItem( |
531 this, *info, | 485 this, *info, |
532 scoped_ptr<DownloadRequestHandleInterface>( | 486 scoped_ptr<DownloadRequestHandleInterface>( |
533 new DownloadRequestHandle(info->request_handle)).Pass(), | 487 new DownloadRequestHandle(info->request_handle)).Pass(), |
534 browser_context_->IsOffTheRecord(), bound_net_log); | 488 browser_context_->IsOffTheRecord(), bound_net_log); |
535 | 489 |
536 DCHECK(!ContainsKey(downloads_, download->GetId())); | 490 DCHECK(!ContainsKey(downloads_, download->GetId())); |
537 downloads_[download->GetId()] = download; | 491 downloads_[download->GetId()] = download; |
538 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | 492 DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
539 active_downloads_[download->GetId()] = download; | 493 active_downloads_[download->GetId()] = download; |
540 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 494 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
541 | 495 |
542 return bound_net_log; | 496 return download; |
543 } | 497 } |
544 | 498 |
545 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 499 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
546 const FilePath& main_file_path, | 500 const FilePath& main_file_path, |
547 const GURL& page_url, | 501 const GURL& page_url, |
548 bool is_otr, | 502 bool is_otr, |
549 const std::string& mime_type, | 503 const std::string& mime_type, |
550 DownloadItem::Observer* observer) { | 504 DownloadItem::Observer* observer) { |
551 net::BoundNetLog bound_net_log = | 505 net::BoundNetLog bound_net_log = |
552 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 506 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
553 DownloadItemImpl* download = factory_->CreateSavePageItem( | 507 DownloadItemImpl* download = item_factory_->CreateSavePageItem( |
554 this, | 508 this, |
555 main_file_path, | 509 main_file_path, |
556 page_url, | 510 page_url, |
557 is_otr, | 511 is_otr, |
558 GetNextId(), | 512 GetNextId(), |
559 mime_type, | 513 mime_type, |
560 bound_net_log); | 514 bound_net_log); |
561 | 515 |
562 download->AddObserver(observer); | 516 download->AddObserver(observer); |
563 | 517 |
564 DCHECK(!ContainsKey(downloads_, download->GetId())); | 518 DCHECK(!ContainsKey(downloads_, download->GetId())); |
565 downloads_[download->GetId()] = download; | 519 downloads_[download->GetId()] = download; |
566 DCHECK(!SavePageData::Get(download)); | 520 DCHECK(!SavePageData::Get(download)); |
567 new SavePageData(download); | 521 new SavePageData(download); |
568 DCHECK(SavePageData::Get(download)); | 522 DCHECK(SavePageData::Get(download)); |
569 | 523 |
570 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when | 524 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when |
571 // we're comfortable with the user interacting with them. | 525 // we're comfortable with the user interacting with them. |
572 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 526 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
573 | 527 |
574 // Will notify the observer in the callback. | 528 // Will notify the observer in the callback. |
575 if (delegate_) | 529 if (delegate_) |
576 delegate_->AddItemToPersistentStore(download); | 530 delegate_->AddItemToPersistentStore(download); |
577 | 531 |
578 return download; | 532 return download; |
579 } | 533 } |
580 | 534 |
581 void DownloadManagerImpl::UpdateDownload(int32 download_id, | |
582 int64 bytes_so_far, | |
583 int64 bytes_per_sec, | |
584 const std::string& hash_state) { | |
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
586 DownloadMap::iterator it = active_downloads_.find(download_id); | |
587 if (it != active_downloads_.end()) { | |
588 DownloadItemImpl* download = it->second; | |
589 if (download->IsInProgress()) { | |
590 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | |
591 if (delegate_) | |
592 delegate_->UpdateItemInPersistentStore(download); | |
593 } | |
594 } | |
595 } | |
596 | |
597 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | |
598 int64 size, | |
599 const std::string& hash) { | |
600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
601 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | |
602 << " size = " << size; | |
603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
604 | |
605 // If it's not in active_downloads_, that means it was cancelled; just | |
606 // ignore the notification. | |
607 if (active_downloads_.count(download_id) == 0) | |
608 return; | |
609 | |
610 DownloadItemImpl* download = active_downloads_[download_id]; | |
611 download->OnAllDataSaved(size, hash); | |
612 MaybeCompleteDownload(download); | |
613 } | |
614 | |
615 void DownloadManagerImpl::AssertStateConsistent( | 535 void DownloadManagerImpl::AssertStateConsistent( |
616 DownloadItemImpl* download) const { | 536 DownloadItemImpl* download) const { |
617 CHECK(ContainsKey(downloads_, download->GetId())); | 537 CHECK(ContainsKey(downloads_, download->GetId())); |
618 | 538 |
619 int64 state = download->GetState(); | 539 int64 state = download->GetState(); |
620 base::debug::Alias(&state); | 540 base::debug::Alias(&state); |
621 if (ContainsKey(active_downloads_, download->GetId())) { | 541 if (ContainsKey(active_downloads_, download->GetId())) { |
622 if (download->IsPersisted()) | 542 if (download->IsPersisted()) |
623 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 543 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
624 if (DownloadItem::IN_PROGRESS != download->GetState()) | 544 if (DownloadItem::IN_PROGRESS != download->GetState()) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { | 646 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
728 | 648 |
729 VLOG(20) << __FUNCTION__ << "()" | 649 VLOG(20) << __FUNCTION__ << "()" |
730 << " download = " << download->DebugString(true); | 650 << " download = " << download->DebugString(true); |
731 | 651 |
732 RemoveFromActiveList(download); | 652 RemoveFromActiveList(download); |
733 // This function is called from the DownloadItem, so DI state | 653 // This function is called from the DownloadItem, so DI state |
734 // should already have been updated. | 654 // should already have been updated. |
735 AssertStateConsistent(download); | 655 AssertStateConsistent(download); |
736 | |
737 DCHECK(file_manager_); | |
738 download->OffThreadCancel(); | |
739 } | |
740 | |
741 void DownloadManagerImpl::OnDownloadInterrupted( | |
742 int32 download_id, | |
743 content::DownloadInterruptReason reason) { | |
744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
745 | |
746 if (!ContainsKey(active_downloads_, download_id)) | |
747 return; | |
748 active_downloads_[download_id]->Interrupt(reason); | |
749 } | 656 } |
750 | 657 |
751 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 658 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
753 DCHECK(download); | 660 DCHECK(download); |
754 | 661 |
755 // Clean up will happen when the history system create callback runs if we | 662 // Clean up will happen when the history system create callback runs if we |
756 // don't have a valid db_handle yet. | 663 // don't have a valid db_handle yet. |
757 if (download->IsPersisted()) { | 664 if (download->IsPersisted()) { |
758 active_downloads_.erase(download->GetId()); | 665 active_downloads_.erase(download->GetId()); |
759 if (delegate_) | 666 if (delegate_) |
760 delegate_->UpdateItemInPersistentStore(download); | 667 delegate_->UpdateItemInPersistentStore(download); |
761 } | 668 } |
762 } | 669 } |
763 | 670 |
764 bool DownloadManagerImpl::GenerateFileHash() { | 671 bool DownloadManagerImpl::GenerateFileHash() { |
765 return delegate_ && delegate_->GenerateFileHash(); | 672 return delegate_ && delegate_->GenerateFileHash(); |
766 } | 673 } |
767 | 674 |
| 675 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( |
| 676 scoped_ptr<content::DownloadFileFactory> file_factory) { |
| 677 file_factory_ = file_factory.Pass(); |
| 678 } |
| 679 |
| 680 content::DownloadFileFactory* |
| 681 DownloadManagerImpl::GetDownloadFileFactoryForTesting() { |
| 682 return file_factory_.get(); |
| 683 } |
| 684 |
768 int DownloadManagerImpl::RemoveDownloadItems( | 685 int DownloadManagerImpl::RemoveDownloadItems( |
769 const DownloadItemImplVector& pending_deletes) { | 686 const DownloadItemImplVector& pending_deletes) { |
770 if (pending_deletes.empty()) | 687 if (pending_deletes.empty()) |
771 return 0; | 688 return 0; |
772 | 689 |
773 // Delete from internal maps. | 690 // Delete from internal maps. |
774 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); | 691 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); |
775 it != pending_deletes.end(); | 692 it != pending_deletes.end(); |
776 ++it) { | 693 ++it) { |
777 DownloadItemImpl* download = *it; | 694 DownloadItemImpl* download = *it; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 782 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
866 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 783 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
867 std::vector<DownloadPersistentStoreInfo>* entries) { | 784 std::vector<DownloadPersistentStoreInfo>* entries) { |
868 history_size_ = entries->size(); | 785 history_size_ = entries->size(); |
869 for (size_t i = 0; i < entries->size(); ++i) { | 786 for (size_t i = 0; i < entries->size(); ++i) { |
870 int64 db_handle = entries->at(i).db_handle; | 787 int64 db_handle = entries->at(i).db_handle; |
871 base::debug::Alias(&db_handle); | 788 base::debug::Alias(&db_handle); |
872 | 789 |
873 net::BoundNetLog bound_net_log = | 790 net::BoundNetLog bound_net_log = |
874 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 791 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
875 DownloadItemImpl* download = factory_->CreatePersistedItem( | 792 DownloadItemImpl* download = item_factory_->CreatePersistedItem( |
876 this, GetNextId(), entries->at(i), bound_net_log); | 793 this, GetNextId(), entries->at(i), bound_net_log); |
877 DCHECK(!ContainsKey(downloads_, download->GetId())); | 794 DCHECK(!ContainsKey(downloads_, download->GetId())); |
878 downloads_[download->GetId()] = download; | 795 downloads_[download->GetId()] = download; |
879 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 796 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
880 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 797 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
881 << " download = " << download->DebugString(true); | 798 << " download = " << download->DebugString(true); |
882 } | 799 } |
883 NotifyModelChanged(); | 800 NotifyModelChanged(); |
884 CheckForHistoryFilesRemoval(); | 801 CheckForHistoryFilesRemoval(); |
885 } | 802 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 ++num_unopened; | 997 ++num_unopened; |
1081 } | 998 } |
1082 download_stats::RecordOpensOutstanding(num_unopened); | 999 download_stats::RecordOpensOutstanding(num_unopened); |
1083 } | 1000 } |
1084 | 1001 |
1085 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 1002 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1086 DownloadItemImpl* download) { | 1003 DownloadItemImpl* download) { |
1087 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1004 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1088 // download->GetFullPath() is only expected to be meaningful after this | 1005 // download->GetFullPath() is only expected to be meaningful after this |
1089 // callback is received. Therefore we can now add the download to a persistent | 1006 // callback is received. Therefore we can now add the download to a persistent |
1090 // store. If the rename failed, we receive an OnDownloadInterrupted() call | 1007 // store. If the rename failed, we processed an interrupt |
1091 // before we receive the DownloadRenamedToIntermediateName() call. | 1008 // before we receive the DownloadRenamedToIntermediateName() call. |
1092 if (delegate_) { | 1009 if (delegate_) { |
1093 delegate_->AddItemToPersistentStore(download); | 1010 delegate_->AddItemToPersistentStore(download); |
1094 } else { | 1011 } else { |
1095 OnItemAddedToPersistentStore(download->GetId(), | 1012 OnItemAddedToPersistentStore(download->GetId(), |
1096 DownloadItem::kUninitializedHandle); | 1013 DownloadItem::kUninitializedHandle); |
1097 } | 1014 } |
1098 } | 1015 } |
1099 | 1016 |
1100 void DownloadManagerImpl::DownloadRenamedToFinalName( | 1017 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1101 DownloadItemImpl* download) { | 1018 DownloadItemImpl* download) { |
1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1019 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1103 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 1020 // If the rename failed, we processed an interrupt before we get here. |
1104 // receive the DownloadRenamedToFinalName() call. | |
1105 if (delegate_) { | 1021 if (delegate_) { |
1106 delegate_->UpdatePathForItemInPersistentStore( | 1022 delegate_->UpdatePathForItemInPersistentStore( |
1107 download, download->GetFullPath()); | 1023 download, download->GetFullPath()); |
1108 } | 1024 } |
1109 } | 1025 } |
OLD | NEW |