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" |
(...skipping 14 matching lines...) Expand all Loading... |
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" |
35 #include "content/public/browser/download_persistent_store_info.h" | |
36 #include "content/public/browser/download_url_parameters.h" | 35 #include "content/public/browser/download_url_parameters.h" |
37 #include "content/public/browser/notification_service.h" | 36 #include "content/public/browser/notification_service.h" |
38 #include "content/public/browser/notification_types.h" | 37 #include "content/public/browser/notification_types.h" |
39 #include "content/public/browser/render_process_host.h" | 38 #include "content/public/browser/render_process_host.h" |
40 #include "content/public/browser/resource_context.h" | 39 #include "content/public/browser/resource_context.h" |
41 #include "content/public/browser/web_contents_delegate.h" | 40 #include "content/public/browser/web_contents_delegate.h" |
42 #include "net/base/load_flags.h" | 41 #include "net/base/load_flags.h" |
43 #include "net/base/upload_data.h" | 42 #include "net/base/upload_data.h" |
44 #include "webkit/glue/webkit_glue.h" | 43 #include "webkit/glue/webkit_glue.h" |
45 | 44 |
46 using content::BrowserThread; | 45 using content::BrowserThread; |
47 using content::DownloadId; | 46 using content::DownloadId; |
48 using content::DownloadItem; | 47 using content::DownloadItem; |
49 using content::DownloadPersistentStoreInfo; | |
50 using content::ResourceDispatcherHostImpl; | 48 using content::ResourceDispatcherHostImpl; |
51 using content::WebContents; | 49 using content::WebContents; |
52 | 50 |
53 namespace { | 51 namespace { |
54 | 52 |
55 // This is just used to remember which DownloadItems come from SavePage. | 53 // This is just used to remember which DownloadItems come from SavePage. |
56 class SavePageData : public base::SupportsUserData::Data { | 54 class SavePageData : public base::SupportsUserData::Data { |
57 public: | 55 public: |
58 // A spoonful of syntactic sugar. | 56 // A spoonful of syntactic sugar. |
59 static bool Get(DownloadItem* item) { | 57 static bool Get(DownloadItem* item) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 160 } |
163 | 161 |
164 class DownloadItemFactoryImpl : public content::DownloadItemFactory { | 162 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
165 public: | 163 public: |
166 DownloadItemFactoryImpl() {} | 164 DownloadItemFactoryImpl() {} |
167 virtual ~DownloadItemFactoryImpl() {} | 165 virtual ~DownloadItemFactoryImpl() {} |
168 | 166 |
169 virtual DownloadItemImpl* CreatePersistedItem( | 167 virtual DownloadItemImpl* CreatePersistedItem( |
170 DownloadItemImplDelegate* delegate, | 168 DownloadItemImplDelegate* delegate, |
171 content::DownloadId download_id, | 169 content::DownloadId download_id, |
172 const content::DownloadPersistentStoreInfo& info, | 170 const FilePath& path, |
| 171 const GURL& url, |
| 172 const GURL& referrer_url, |
| 173 const base::Time& start_time, |
| 174 const base::Time& end_time, |
| 175 int64 received_bytes, |
| 176 int64 total_bytes, |
| 177 DownloadItem::DownloadState state, |
| 178 bool opened, |
173 const net::BoundNetLog& bound_net_log) OVERRIDE { | 179 const net::BoundNetLog& bound_net_log) OVERRIDE { |
174 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); | 180 return new DownloadItemImpl( |
| 181 delegate, |
| 182 download_id, |
| 183 path, |
| 184 url, |
| 185 referrer_url, |
| 186 start_time, |
| 187 end_time, |
| 188 received_bytes, |
| 189 total_bytes, |
| 190 state, |
| 191 opened, |
| 192 bound_net_log); |
175 } | 193 } |
176 | 194 |
177 virtual DownloadItemImpl* CreateActiveItem( | 195 virtual DownloadItemImpl* CreateActiveItem( |
178 DownloadItemImplDelegate* delegate, | 196 DownloadItemImplDelegate* delegate, |
179 const DownloadCreateInfo& info, | 197 const DownloadCreateInfo& info, |
180 scoped_ptr<DownloadRequestHandleInterface> request_handle, | 198 scoped_ptr<DownloadRequestHandleInterface> request_handle, |
181 const net::BoundNetLog& bound_net_log) OVERRIDE { | 199 const net::BoundNetLog& bound_net_log) OVERRIDE { |
182 return new DownloadItemImpl(delegate, info, request_handle.Pass(), | 200 return new DownloadItemImpl(delegate, info, request_handle.Pass(), |
183 bound_net_log); | 201 bound_net_log); |
184 } | 202 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 // from the disk. This may or may not result in it being | 322 // from the disk. This may or may not result in it being |
305 // removed from the DownloadManager queues and deleted | 323 // removed from the DownloadManager queues and deleted |
306 // (specifically, DownloadManager::DownloadRemoved only | 324 // (specifically, DownloadManager::DownloadRemoved only |
307 // removes and deletes it if it's known to the history service) | 325 // removes and deletes it if it's known to the history service) |
308 // so the only thing we know after calling this function is that | 326 // so the only thing we know after calling this function is that |
309 // the download was deleted if-and-only-if it was removed | 327 // the download was deleted if-and-only-if it was removed |
310 // from all queues. | 328 // from all queues. |
311 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); | 329 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); |
312 } else if (download->IsPartialDownload()) { | 330 } else if (download->IsPartialDownload()) { |
313 download->Cancel(false); | 331 download->Cancel(false); |
314 if (delegate_) | |
315 delegate_->UpdateItemInPersistentStore(download); | |
316 } | 332 } |
317 } | 333 } |
318 | 334 |
319 // At this point, all dangerous downloads have had their files removed | 335 // At this point, all dangerous downloads have had their files removed |
320 // and all in progress downloads have been cancelled. We can now delete | 336 // and all in progress downloads have been cancelled. We can now delete |
321 // anything left. | 337 // anything left. |
322 | 338 |
323 active_downloads_.clear(); | 339 active_downloads_.clear(); |
324 STLDeleteValues(&downloads_); | 340 STLDeleteValues(&downloads_); |
325 downloads_.clear(); | 341 downloads_.clear(); |
326 | 342 |
327 // We'll have nothing more to report to the observers after this point. | 343 // We'll have nothing more to report to the observers after this point. |
328 observers_.Clear(); | 344 observers_.Clear(); |
329 | 345 |
330 file_manager_ = NULL; | 346 file_manager_ = NULL; |
331 if (delegate_) | 347 if (delegate_) |
332 delegate_->Shutdown(); | 348 delegate_->Shutdown(); |
333 delegate_ = NULL; | 349 delegate_ = NULL; |
334 } | 350 } |
335 | 351 |
336 void DownloadManagerImpl::GetTemporaryDownloads( | 352 void DownloadManagerImpl::GetTemporaryDownloads( |
337 const FilePath& dir_path, DownloadVector* result) { | 353 const FilePath& dir_path, DownloadVector* result) { |
338 DCHECK(result); | 354 DCHECK(result); |
339 | 355 |
340 for (DownloadMap::iterator it = downloads_.begin(); | 356 for (DownloadMap::iterator it = downloads_.begin(); |
341 it != downloads_.end(); ++it) { | 357 it != downloads_.end(); ++it) { |
342 DownloadItemImpl* item = it->second; | 358 DownloadItemImpl* item = it->second; |
343 // TODO(benjhayden): Don't check IsPersisted(). | |
344 if (item->IsTemporary() && | 359 if (item->IsTemporary() && |
345 item->IsPersisted() && | |
346 (dir_path.empty() || | 360 (dir_path.empty() || |
347 item->GetTargetFilePath().DirName() == dir_path)) | 361 item->GetTargetFilePath().DirName() == dir_path)) |
348 result->push_back(item); | 362 result->push_back(item); |
349 } | 363 } |
350 } | 364 } |
351 | 365 |
352 void DownloadManagerImpl::GetAllDownloads( | 366 void DownloadManagerImpl::GetAllDownloads( |
353 const FilePath& dir_path, DownloadVector* result) { | 367 const FilePath& dir_path, DownloadVector* result) { |
354 DCHECK(result); | 368 DCHECK(result); |
355 | 369 |
356 for (DownloadMap::iterator it = downloads_.begin(); | 370 for (DownloadMap::iterator it = downloads_.begin(); |
357 it != downloads_.end(); ++it) { | 371 it != downloads_.end(); ++it) { |
358 DownloadItemImpl* item = it->second; | 372 DownloadItemImpl* item = it->second; |
359 // TODO(benjhayden): Don't check IsPersisted(). | |
360 if (!item->IsTemporary() && | 373 if (!item->IsTemporary() && |
361 item->IsPersisted() && | |
362 (dir_path.empty() || | 374 (dir_path.empty() || |
363 item->GetTargetFilePath().DirName() == dir_path)) | 375 item->GetTargetFilePath().DirName() == dir_path)) |
364 result->push_back(item); | 376 result->push_back(item); |
365 } | 377 } |
366 } | 378 } |
367 | 379 |
368 void DownloadManagerImpl::SearchDownloads(const string16& query, | 380 void DownloadManagerImpl::SearchDownloads(const string16& query, |
369 DownloadVector* result) { | 381 DownloadVector* result) { |
370 string16 query_lower(base::i18n::ToLower(query)); | 382 string16 query_lower(base::i18n::ToLower(query)); |
371 | 383 |
372 for (DownloadMap::iterator it = downloads_.begin(); | 384 for (DownloadMap::iterator it = downloads_.begin(); |
373 it != downloads_.end(); ++it) { | 385 it != downloads_.end(); ++it) { |
374 DownloadItemImpl* download_item = it->second; | 386 DownloadItemImpl* download_item = it->second; |
375 // TODO(benjhayden): Don't check IsPersisted(). | |
376 if (!download_item->IsTemporary() && | 387 if (!download_item->IsTemporary() && |
377 download_item->IsPersisted() && | |
378 download_item->MatchesQuery(query_lower)) { | 388 download_item->MatchesQuery(query_lower)) { |
379 result->push_back(download_item); | 389 result->push_back(download_item); |
380 } | 390 } |
381 } | 391 } |
382 } | 392 } |
383 | 393 |
384 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 394 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
385 DCHECK(browser_context); | 395 DCHECK(browser_context); |
386 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 396 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
387 shutdown_needed_ = true; | 397 shutdown_needed_ = true; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 } | 462 } |
453 } | 463 } |
454 | 464 |
455 void DownloadManagerImpl::OnDownloadTargetDetermined( | 465 void DownloadManagerImpl::OnDownloadTargetDetermined( |
456 int32 download_id, | 466 int32 download_id, |
457 const FilePath& target_path, | 467 const FilePath& target_path, |
458 DownloadItem::TargetDisposition disposition, | 468 DownloadItem::TargetDisposition disposition, |
459 content::DownloadDangerType danger_type, | 469 content::DownloadDangerType danger_type, |
460 const FilePath& intermediate_path) { | 470 const FilePath& intermediate_path) { |
461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
462 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 472 DownloadMap::iterator download_iter = downloads_.find(download_id); |
463 if (download_iter != active_downloads_.end()) { | 473 if (download_iter == downloads_.end()) |
464 // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a | 474 return; |
465 // DownloadRenamedToIntermediateName() callback. This is necessary for the | 475 |
466 // download to proceed. | 476 // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a |
467 download_iter->second->OnDownloadTargetDetermined( | 477 // DownloadRenamedToIntermediateName() callback. This is necessary for the |
468 target_path, disposition, danger_type, intermediate_path); | 478 // download to proceed. |
| 479 DownloadItemImpl* item = download_iter->second; |
| 480 item->OnDownloadTargetDetermined( |
| 481 target_path, disposition, danger_type, intermediate_path); |
| 482 ShowDownloadInBrowser(item); |
| 483 NotifyModelChanged(); |
| 484 if (!SavePageData::Get(item)) { |
| 485 MaybeCompleteDownload(item); |
469 } | 486 } |
470 } | 487 } |
471 | 488 |
472 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { | 489 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
474 for (DownloadMap::iterator it = downloads_.begin(); | 491 for (DownloadMap::iterator it = downloads_.begin(); |
475 it != downloads_.end(); ++it) { | 492 it != downloads_.end(); ++it) { |
476 DownloadItemImpl* item = it->second; | 493 DownloadItemImpl* item = it->second; |
477 if (item->IsPersisted()) | 494 CheckForFileRemoval(item); |
478 CheckForFileRemoval(item); | |
479 } | 495 } |
480 } | 496 } |
481 | 497 |
482 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { | 498 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { |
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
484 if (download_item->IsComplete() && | 500 if (download_item->IsComplete() && |
485 !download_item->GetFileExternallyRemoved()) { | 501 !download_item->GetFileExternallyRemoved()) { |
486 BrowserThread::PostTask( | 502 BrowserThread::PostTask( |
487 BrowserThread::FILE, FROM_HERE, | 503 BrowserThread::FILE, FROM_HERE, |
488 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, | 504 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 return bound_net_log; | 552 return bound_net_log; |
537 } | 553 } |
538 | 554 |
539 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 555 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
540 const FilePath& main_file_path, | 556 const FilePath& main_file_path, |
541 const GURL& page_url, | 557 const GURL& page_url, |
542 const std::string& mime_type, | 558 const std::string& mime_type, |
543 DownloadItem::Observer* observer) { | 559 DownloadItem::Observer* observer) { |
544 net::BoundNetLog bound_net_log = | 560 net::BoundNetLog bound_net_log = |
545 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 561 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
546 DownloadItemImpl* download = factory_->CreateSavePageItem( | 562 DownloadItemImpl* download_item = factory_->CreateSavePageItem( |
547 this, | 563 this, |
548 main_file_path, | 564 main_file_path, |
549 page_url, | 565 page_url, |
550 GetNextId(), | 566 GetNextId(), |
551 mime_type, | 567 mime_type, |
552 bound_net_log); | 568 bound_net_log); |
553 | 569 download_item->AddObserver(observer); |
554 download->AddObserver(observer); | 570 DCHECK(!ContainsKey(downloads_, download_item->GetId())); |
555 | 571 downloads_[download_item->GetId()] = download_item; |
556 DCHECK(!ContainsKey(downloads_, download->GetId())); | 572 DCHECK(!SavePageData::Get(download_item)); |
557 downloads_[download->GetId()] = download; | 573 new SavePageData(download_item); |
558 DCHECK(!SavePageData::Get(download)); | 574 DCHECK(SavePageData::Get(download_item)); |
559 new SavePageData(download); | 575 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated( |
560 DCHECK(SavePageData::Get(download)); | 576 this, download_item)); |
561 | 577 OnDownloadTargetDetermined( |
562 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 578 download_item->GetId(), |
563 | 579 main_file_path, |
564 // Will notify the observer in the callback. | 580 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
565 if (delegate_) | 581 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
566 delegate_->AddItemToPersistentStore(download); | 582 main_file_path); |
567 | 583 return download_item; |
568 return download; | |
569 } | 584 } |
570 | 585 |
571 void DownloadManagerImpl::UpdateDownload(int32 download_id, | 586 void DownloadManagerImpl::UpdateDownload(int32 download_id, |
572 int64 bytes_so_far, | 587 int64 bytes_so_far, |
573 int64 bytes_per_sec, | 588 int64 bytes_per_sec, |
574 const std::string& hash_state) { | 589 const std::string& hash_state) { |
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
576 DownloadMap::iterator it = active_downloads_.find(download_id); | 591 DownloadMap::iterator it = active_downloads_.find(download_id); |
577 if (it != active_downloads_.end()) { | 592 if (it != active_downloads_.end()) { |
578 DownloadItemImpl* download = it->second; | 593 DownloadItemImpl* download = it->second; |
579 if (download->IsInProgress()) { | 594 if (download->IsInProgress()) { |
580 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | 595 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); |
581 if (delegate_) | |
582 delegate_->UpdateItemInPersistentStore(download); | |
583 } | 596 } |
584 } | 597 } |
585 } | 598 } |
586 | 599 |
587 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | 600 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, |
588 int64 size, | 601 int64 size, |
589 const std::string& hash) { | 602 const std::string& hash) { |
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
591 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 604 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
592 << " size = " << size; | 605 << " size = " << size; |
593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
594 | 607 |
595 // If it's not in active_downloads_, that means it was cancelled; just | 608 // If it's not in active_downloads_, that means it was cancelled; just |
596 // ignore the notification. | 609 // ignore the notification. |
597 if (active_downloads_.count(download_id) == 0) | 610 if (active_downloads_.count(download_id) == 0) |
598 return; | 611 return; |
599 | 612 |
600 DownloadItemImpl* download = active_downloads_[download_id]; | 613 DownloadItemImpl* download = active_downloads_[download_id]; |
601 download->OnAllDataSaved(size, hash); | 614 download->OnAllDataSaved(size, hash); |
602 MaybeCompleteDownload(download); | 615 MaybeCompleteDownload(download); |
603 } | 616 } |
604 | 617 |
605 void DownloadManagerImpl::AssertStateConsistent( | 618 void DownloadManagerImpl::AssertStateConsistent( |
606 DownloadItemImpl* download) const { | 619 DownloadItemImpl* download) const { |
607 CHECK(ContainsKey(downloads_, download->GetId())); | 620 CHECK(ContainsKey(downloads_, download->GetId())); |
608 | 621 |
609 int64 state = download->GetState(); | 622 int64 state = download->GetState(); |
610 base::debug::Alias(&state); | 623 base::debug::Alias(&state); |
611 if (ContainsKey(active_downloads_, download->GetId())) { | |
612 if (download->IsPersisted()) | |
613 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | |
614 if (DownloadItem::IN_PROGRESS != download->GetState()) | |
615 CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle()); | |
616 } | |
617 if (DownloadItem::IN_PROGRESS == download->GetState()) | 624 if (DownloadItem::IN_PROGRESS == download->GetState()) |
618 CHECK(ContainsKey(active_downloads_, download->GetId())); | 625 CHECK(ContainsKey(active_downloads_, download->GetId())); |
619 } | 626 } |
620 | 627 |
621 bool DownloadManagerImpl::IsDownloadReadyForCompletion( | 628 bool DownloadManagerImpl::IsDownloadReadyForCompletion( |
622 DownloadItemImpl* download) { | 629 DownloadItemImpl* download) { |
623 // If we don't have all the data, the download is not ready for | 630 // If we don't have all the data, the download is not ready for |
624 // completion. | 631 // completion. |
625 if (!download->AllDataSaved()) | 632 if (!download->AllDataSaved()) |
626 return false; | 633 return false; |
627 | 634 |
628 // If the download is dangerous, but not yet validated, it's not ready for | 635 // If the download is dangerous, but not yet validated, it's not ready for |
629 // completion. | 636 // completion. |
630 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 637 if (download->GetSafetyState() == DownloadItem::DANGEROUS) |
631 return false; | 638 return false; |
632 | 639 |
633 // If the download isn't active (e.g. has been cancelled) it's not | 640 // If the download isn't active (e.g. has been cancelled) it's not |
634 // ready for completion. | 641 // ready for completion. |
635 if (active_downloads_.count(download->GetId()) == 0) | 642 if (active_downloads_.count(download->GetId()) == 0) |
636 return false; | 643 return false; |
637 | 644 |
638 // If the download hasn't been inserted into the history system | 645 if (download->GetTargetFilePath().DirName() != |
639 // (which occurs strictly after file name determination, intermediate | 646 download->GetFullPath().DirName()) |
640 // file rename, and UI display) then it's not ready for completion. | 647 return false; |
641 if (!download->IsPersisted()) | 648 if (download->GetTargetName().empty()) |
642 return false; | 649 return false; |
643 | 650 |
644 return true; | 651 return true; |
645 } | 652 } |
646 | 653 |
647 // When SavePackage downloads MHTML to GData (see | 654 // When SavePackage downloads MHTML to GData (see |
648 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 655 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
649 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 656 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
650 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 657 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
651 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage | 658 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage |
(...skipping 13 matching lines...) Expand all Loading... |
665 | 672 |
666 // TODO(rdsmith): DCHECK that we only pass through this point | 673 // TODO(rdsmith): DCHECK that we only pass through this point |
667 // once per download. The natural way to do this is by a state | 674 // once per download. The natural way to do this is by a state |
668 // transition on the DownloadItem. | 675 // transition on the DownloadItem. |
669 | 676 |
670 // Confirm we're in the proper set of states to be here; | 677 // Confirm we're in the proper set of states to be here; |
671 // have all data, have a history handle, (validated or safe). | 678 // have all data, have a history handle, (validated or safe). |
672 DCHECK(download->IsInProgress()); | 679 DCHECK(download->IsInProgress()); |
673 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); | 680 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); |
674 DCHECK(download->AllDataSaved()); | 681 DCHECK(download->AllDataSaved()); |
675 DCHECK(download->IsPersisted()); | |
676 | 682 |
677 // Give the delegate a chance to override. It's ok to keep re-setting the | 683 // Give the delegate a chance to override. It's ok to keep re-setting the |
678 // delegate's |complete_callback| cb as long as there isn't another call-point | 684 // delegate's |complete_callback| cb as long as there isn't another call-point |
679 // trying to set it to a different cb. TODO(benjhayden): Change the callback | 685 // trying to set it to a different cb. TODO(benjhayden): Change the callback |
680 // to point directly to the item instead of |this| when DownloadItem supports | 686 // to point directly to the item instead of |this| when DownloadItem supports |
681 // weak-ptrs. | 687 // weak-ptrs. |
682 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( | 688 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( |
683 &DownloadManagerImpl::MaybeCompleteDownloadById, | 689 &DownloadManagerImpl::MaybeCompleteDownloadById, |
684 this, download->GetId()))) | 690 this, download->GetId()))) |
685 return; | 691 return; |
686 | 692 |
687 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " | 693 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " |
688 << download->DebugString(false); | 694 << download->DebugString(false); |
689 | 695 |
690 if (delegate_) | |
691 delegate_->UpdateItemInPersistentStore(download); | |
692 download->OnDownloadCompleting(); | 696 download->OnDownloadCompleting(); |
693 } | 697 } |
694 | 698 |
695 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { | 699 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { |
696 if (ContainsKey(active_downloads_, download_id)) | 700 if (ContainsKey(active_downloads_, download_id)) |
697 MaybeCompleteDownload(active_downloads_[download_id]); | 701 MaybeCompleteDownload(active_downloads_[download_id]); |
698 } | 702 } |
699 | 703 |
700 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { | 704 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { |
701 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
702 DCHECK(download); | 706 DCHECK(download); |
703 if (delegate_) | |
704 delegate_->UpdateItemInPersistentStore(download); | |
705 active_downloads_.erase(download->GetId()); | 707 active_downloads_.erase(download->GetId()); |
706 AssertStateConsistent(download); | 708 AssertStateConsistent(download); |
707 } | 709 } |
708 | 710 |
709 void DownloadManagerImpl::CancelDownload(int32 download_id) { | 711 void DownloadManagerImpl::CancelDownload(int32 download_id) { |
710 // A cancel at the right time could remove the download from the | 712 // A cancel at the right time could remove the download from the |
711 // |active_downloads_| map before we get here. | 713 // |active_downloads_| map before we get here. |
712 if (ContainsKey(active_downloads_, download_id)) | 714 if (ContainsKey(active_downloads_, download_id)) |
713 active_downloads_[download_id]->Cancel(true); | 715 active_downloads_[download_id]->Cancel(true); |
714 } | 716 } |
(...skipping 19 matching lines...) Expand all Loading... |
734 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
735 | 737 |
736 if (!ContainsKey(active_downloads_, download_id)) | 738 if (!ContainsKey(active_downloads_, download_id)) |
737 return; | 739 return; |
738 active_downloads_[download_id]->Interrupt(reason); | 740 active_downloads_[download_id]->Interrupt(reason); |
739 } | 741 } |
740 | 742 |
741 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 743 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
743 DCHECK(download); | 745 DCHECK(download); |
744 | 746 active_downloads_.erase(download->GetId()); |
745 // Clean up will happen when the history system create callback runs if we | |
746 // don't have a valid db_handle yet. | |
747 if (download->IsPersisted()) { | |
748 active_downloads_.erase(download->GetId()); | |
749 if (delegate_) | |
750 delegate_->UpdateItemInPersistentStore(download); | |
751 } | |
752 } | 747 } |
753 | 748 |
754 bool DownloadManagerImpl::GenerateFileHash() { | 749 bool DownloadManagerImpl::GenerateFileHash() { |
755 return delegate_ && delegate_->GenerateFileHash(); | 750 return delegate_ && delegate_->GenerateFileHash(); |
756 } | 751 } |
757 | 752 |
758 int DownloadManagerImpl::RemoveDownloadItems( | 753 int DownloadManagerImpl::RemoveDownloadItems( |
759 const DownloadItemImplVector& pending_deletes) { | 754 const DownloadItemImplVector& pending_deletes) { |
760 if (pending_deletes.empty()) | 755 if (pending_deletes.empty()) |
761 return 0; | 756 return 0; |
(...skipping 10 matching lines...) Expand all Loading... |
772 } | 767 } |
773 NotifyModelChanged(); | 768 NotifyModelChanged(); |
774 return static_cast<int>(pending_deletes.size()); | 769 return static_cast<int>(pending_deletes.size()); |
775 } | 770 } |
776 | 771 |
777 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { | 772 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { |
778 if (!download || | 773 if (!download || |
779 downloads_.find(download->GetId()) == downloads_.end()) | 774 downloads_.find(download->GetId()) == downloads_.end()) |
780 return; | 775 return; |
781 | 776 |
782 // TODO(benjhayden,rdsmith): Remove this. | |
783 if (!download->IsPersisted()) | |
784 return; | |
785 | |
786 // Make history update. | |
787 if (delegate_) | |
788 delegate_->RemoveItemFromPersistentStore(download); | |
789 | |
790 // Remove from our tables and delete. | 777 // Remove from our tables and delete. |
791 int downloads_count = | 778 int downloads_count = |
792 RemoveDownloadItems(DownloadItemImplVector(1, download)); | 779 RemoveDownloadItems(DownloadItemImplVector(1, download)); |
793 DCHECK_EQ(1, downloads_count); | 780 DCHECK_EQ(1, downloads_count); |
794 } | 781 } |
795 | 782 |
796 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, | 783 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, |
797 base::Time remove_end) { | 784 base::Time remove_end) { |
798 if (delegate_) | |
799 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); | |
800 | |
801 DownloadItemImplVector pending_deletes; | 785 DownloadItemImplVector pending_deletes; |
802 for (DownloadMap::const_iterator it = downloads_.begin(); | 786 for (DownloadMap::const_iterator it = downloads_.begin(); |
803 it != downloads_.end(); | 787 it != downloads_.end(); |
804 ++it) { | 788 ++it) { |
805 DownloadItemImpl* download = it->second; | 789 DownloadItemImpl* download = it->second; |
806 if (download->IsPersisted() && | 790 if (download->GetStartTime() >= remove_begin && |
807 download->GetStartTime() >= remove_begin && | |
808 (remove_end.is_null() || download->GetStartTime() < remove_end) && | 791 (remove_end.is_null() || download->GetStartTime() < remove_end) && |
809 (download->IsComplete() || download->IsCancelled())) { | 792 (download->IsComplete() || download->IsCancelled())) { |
810 AssertStateConsistent(download); | 793 AssertStateConsistent(download); |
811 download->NotifyRemoved(); | 794 download->NotifyRemoved(); |
812 pending_deletes.push_back(download); | 795 pending_deletes.push_back(download); |
813 } | 796 } |
814 } | 797 } |
815 return RemoveDownloadItems(pending_deletes); | 798 return RemoveDownloadItems(pending_deletes); |
816 } | 799 } |
817 | 800 |
(...skipping 26 matching lines...) Expand all Loading... |
844 // observers. | 827 // observers. |
845 observer->ModelChanged(this); | 828 observer->ModelChanged(this); |
846 } | 829 } |
847 | 830 |
848 void DownloadManagerImpl::RemoveObserver(Observer* observer) { | 831 void DownloadManagerImpl::RemoveObserver(Observer* observer) { |
849 observers_.RemoveObserver(observer); | 832 observers_.RemoveObserver(observer); |
850 } | 833 } |
851 | 834 |
852 // Operations posted to us from the history service ---------------------------- | 835 // Operations posted to us from the history service ---------------------------- |
853 | 836 |
854 // The history service has retrieved all download entries. 'entries' contains | 837 DownloadItem* DownloadManagerImpl::CreateDownloadItem( |
855 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 838 const FilePath& path, |
856 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 839 const GURL& url, |
857 std::vector<DownloadPersistentStoreInfo>* entries) { | 840 const GURL& referrer_url, |
858 history_size_ = entries->size(); | 841 const base::Time& start_time, |
859 for (size_t i = 0; i < entries->size(); ++i) { | 842 const base::Time& end_time, |
860 int64 db_handle = entries->at(i).db_handle; | 843 int64 received_bytes, |
861 base::debug::Alias(&db_handle); | 844 int64 total_bytes, |
862 | 845 DownloadItem::DownloadState state, |
863 net::BoundNetLog bound_net_log = | 846 bool opened) { |
864 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 847 DownloadItemImpl* item = factory_->CreatePersistedItem( |
865 DownloadItemImpl* download = factory_->CreatePersistedItem( | 848 this, |
866 this, GetNextId(), entries->at(i), bound_net_log); | 849 GetNextId(), |
867 DCHECK(!ContainsKey(downloads_, download->GetId())); | 850 path, |
868 downloads_[download->GetId()] = download; | 851 url, |
869 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 852 referrer_url, |
870 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 853 start_time, |
871 << " download = " << download->DebugString(true); | 854 end_time, |
872 } | 855 received_bytes, |
| 856 total_bytes, |
| 857 state, |
| 858 opened, |
| 859 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD)); |
| 860 DCHECK(!ContainsKey(downloads_, item->GetId())); |
| 861 downloads_[item->GetId()] = item; |
| 862 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, item)); |
| 863 VLOG(20) << __FUNCTION__ << "() download = " << item->DebugString(true); |
873 NotifyModelChanged(); | 864 NotifyModelChanged(); |
874 CheckForHistoryFilesRemoval(); | 865 return item; |
875 } | |
876 | |
877 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download, | |
878 int64 db_handle) { | |
879 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
880 DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle); | |
881 DCHECK(!download->IsPersisted()); | |
882 download->SetDbHandle(db_handle); | |
883 download->SetIsPersisted(); | |
884 | |
885 download_stats::RecordHistorySize(history_size_); | |
886 // Not counting |download|. | |
887 ++history_size_; | |
888 | |
889 // Show in the appropriate browser UI. | |
890 // This includes buttons to save or cancel, for a dangerous download. | |
891 ShowDownloadInBrowser(download); | |
892 | |
893 // Inform interested objects about the new download. | |
894 NotifyModelChanged(); | |
895 } | |
896 | |
897 | |
898 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, | |
899 int64 db_handle) { | |
900 // It's valid that we don't find a matching item, i.e. on shutdown. | |
901 if (!ContainsKey(downloads_, download_id)) | |
902 return; | |
903 | |
904 DownloadItemImpl* item = downloads_[download_id]; | |
905 AddDownloadItemToHistory(item, db_handle); | |
906 if (SavePageData::Get(item)) { | |
907 OnSavePageItemAddedToPersistentStore(item); | |
908 } else { | |
909 OnDownloadItemAddedToPersistentStore(item); | |
910 } | |
911 } | |
912 | |
913 // Once the new DownloadItem has been committed to the persistent store, | |
914 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), | |
915 // show it in the browser (TODO(benjhayden) the ui should observe us instead), | |
916 // and notify observers (TODO(benjhayden) observers should be able to see the | |
917 // item when it's created so they can observe it directly. Are there any | |
918 // clients that actually need to know when the item is added to the history?). | |
919 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore( | |
920 DownloadItemImpl* item) { | |
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
922 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle() | |
923 << " download_id = " << item->GetId() | |
924 << " download = " << item->DebugString(true); | |
925 | |
926 // If the download is still in progress, try to complete it. | |
927 // | |
928 // Otherwise, download has been cancelled or interrupted before we've | |
929 // received the DB handle. We post one final message to the history | |
930 // service so that it can be properly in sync with the DownloadItem's | |
931 // completion status, and also inform any observers so that they get | |
932 // more than just the start notification. | |
933 if (item->IsInProgress()) { | |
934 MaybeCompleteDownload(item); | |
935 } else { | |
936 DCHECK(item->IsCancelled()); | |
937 active_downloads_.erase(item->GetId()); | |
938 if (delegate_) | |
939 delegate_->UpdateItemInPersistentStore(item); | |
940 item->UpdateObservers(); | |
941 } | |
942 } | 866 } |
943 | 867 |
944 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { | 868 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { |
945 // The 'contents' may no longer exist if the user closed the contents before | 869 // The 'contents' may no longer exist if the user closed the contents before |
946 // we get this start completion event. | 870 // we get this start completion event. |
947 WebContents* content = download->GetWebContents(); | 871 WebContents* content = download->GetWebContents(); |
948 | 872 |
949 // If the contents no longer exists, we ask the embedder to suggest another | 873 // If the contents no longer exists, we ask the embedder to suggest another |
950 // contents. | 874 // contents. |
951 if (!content && delegate_) | 875 if (!content && delegate_) |
(...skipping 15 matching lines...) Expand all Loading... |
967 ++count; | 891 ++count; |
968 } | 892 } |
969 return count; | 893 return count; |
970 } | 894 } |
971 | 895 |
972 void DownloadManagerImpl::NotifyModelChanged() { | 896 void DownloadManagerImpl::NotifyModelChanged() { |
973 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); | 897 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); |
974 } | 898 } |
975 | 899 |
976 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { | 900 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { |
977 DownloadItem* download = GetDownload(download_id); | 901 return GetDownload(download_id); |
978 return (download && download->IsPersisted()) ? download : NULL; | |
979 } | 902 } |
980 | 903 |
981 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { | 904 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { |
982 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; | 905 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; |
983 } | 906 } |
984 | 907 |
985 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { | 908 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { |
986 if (ContainsKey(active_downloads_, download_id)) | 909 if (ContainsKey(active_downloads_, download_id)) |
987 return active_downloads_[download_id]; | 910 return active_downloads_[download_id]; |
988 return NULL; | 911 return NULL; |
(...skipping 26 matching lines...) Expand all Loading... |
1015 DownloadSet remainder; | 938 DownloadSet remainder; |
1016 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); | 939 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); |
1017 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), | 940 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), |
1018 all_downloads.begin(), all_downloads.end(), | 941 all_downloads.begin(), all_downloads.end(), |
1019 insert_it); | 942 insert_it); |
1020 DCHECK(remainder.empty()); | 943 DCHECK(remainder.empty()); |
1021 } | 944 } |
1022 #endif | 945 #endif |
1023 } | 946 } |
1024 | 947 |
1025 // SavePackage will call SavePageDownloadFinished upon completion/cancellation. | |
1026 // The history callback will call OnSavePageItemAddedToPersistentStore. | |
1027 // If the download finishes before the history callback, | |
1028 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring | |
1029 // that the history event is update regardless of the order in which these two | |
1030 // events complete. | |
1031 // If something removes the download item from the download manager (Remove, | |
1032 // Shutdown) the result will be that the SavePage system will not be able to | |
1033 // properly update the download item (which no longer exists) or the download | |
1034 // history, but the action will complete properly anyway. This may lead to the | |
1035 // history entry being wrong on a reload of chrome (specifically in the case of | |
1036 // Initiation -> History Callback -> Removal -> Completion), but there's no way | |
1037 // to solve that without canceling on Remove (which would then update the DB). | |
1038 | |
1039 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore( | |
1040 DownloadItemImpl* item) { | |
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1042 | |
1043 // Finalize this download if it finished before the history callback. | |
1044 if (!item->IsInProgress()) | |
1045 SavePageDownloadFinished(item); | |
1046 } | |
1047 | |
1048 void DownloadManagerImpl::SavePageDownloadFinished( | 948 void DownloadManagerImpl::SavePageDownloadFinished( |
1049 content::DownloadItem* download) { | 949 content::DownloadItem* download) { |
1050 if (download->IsPersisted()) { | 950 if (download->IsComplete()) |
1051 if (delegate_) | 951 content::NotificationService::current()->Notify( |
1052 delegate_->UpdateItemInPersistentStore(download); | 952 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
1053 if (download->IsComplete()) | 953 content::Source<DownloadManager>(this), |
1054 content::NotificationService::current()->Notify( | 954 content::Details<DownloadItem>(download)); |
1055 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | |
1056 content::Source<DownloadManager>(this), | |
1057 content::Details<DownloadItem>(download)); | |
1058 } | |
1059 } | 955 } |
1060 | 956 |
1061 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { | 957 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { |
1062 if (delegate_) | |
1063 delegate_->UpdateItemInPersistentStore(download); | |
1064 int num_unopened = 0; | 958 int num_unopened = 0; |
1065 for (DownloadMap::iterator it = downloads_.begin(); | 959 for (DownloadMap::iterator it = downloads_.begin(); |
1066 it != downloads_.end(); ++it) { | 960 it != downloads_.end(); ++it) { |
1067 DownloadItemImpl* item = it->second; | 961 DownloadItemImpl* item = it->second; |
1068 if (item->IsComplete() && | 962 if (item->IsComplete() && |
1069 !item->GetOpened()) | 963 !item->GetOpened()) |
1070 ++num_unopened; | 964 ++num_unopened; |
1071 } | 965 } |
1072 download_stats::RecordOpensOutstanding(num_unopened); | 966 download_stats::RecordOpensOutstanding(num_unopened); |
1073 } | 967 } |
1074 | 968 |
| 969 // TODO(benjhayden) this should be a method on DI |
1075 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 970 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1076 DownloadItemImpl* download) { | 971 DownloadItemImpl* download) { |
1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 972 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1078 // download->GetFullPath() is only expected to be meaningful after this | 973 download->UpdateObservers(); |
1079 // callback is received. Therefore we can now add the download to a persistent | 974 MaybeCompleteDownload(download); |
1080 // store. If the rename failed, we receive an OnDownloadInterrupted() call | |
1081 // before we receive the DownloadRenamedToIntermediateName() call. | |
1082 if (delegate_) { | |
1083 delegate_->AddItemToPersistentStore(download); | |
1084 } else { | |
1085 OnItemAddedToPersistentStore(download->GetId(), | |
1086 DownloadItem::kUninitializedHandle); | |
1087 } | |
1088 } | 975 } |
1089 | 976 |
| 977 // TODO(benjhayden) this should be a method on DI |
1090 void DownloadManagerImpl::DownloadRenamedToFinalName( | 978 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1091 DownloadItemImpl* download) { | 979 DownloadItemImpl* download) { |
1092 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 980 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1093 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 981 // If the rename failed, we receive an OnDownloadInterrupted() call before we |
1094 // receive the DownloadRenamedToFinalName() call. | 982 // receive the DownloadRenamedToFinalName() call. |
1095 if (delegate_) { | 983 download->UpdateObservers(); |
1096 delegate_->UpdatePathForItemInPersistentStore( | |
1097 download, download->GetFullPath()); | |
1098 } | |
1099 } | 984 } |
OLD | NEW |