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 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when | 578 download_item->GetId(), |
563 // we're comfortable with the user interacting with them. | 579 main_file_path, |
564 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 580 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
565 | 581 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
566 // Will notify the observer in the callback. | 582 main_file_path); |
567 if (delegate_) | 583 return download_item; |
568 delegate_->AddItemToPersistentStore(download); | |
569 | |
570 return download; | |
571 } | 584 } |
572 | 585 |
573 void DownloadManagerImpl::UpdateDownload(int32 download_id, | 586 void DownloadManagerImpl::UpdateDownload(int32 download_id, |
574 int64 bytes_so_far, | 587 int64 bytes_so_far, |
575 int64 bytes_per_sec, | 588 int64 bytes_per_sec, |
576 const std::string& hash_state) { | 589 const std::string& hash_state) { |
577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
578 DownloadMap::iterator it = active_downloads_.find(download_id); | 591 DownloadMap::iterator it = active_downloads_.find(download_id); |
579 if (it != active_downloads_.end()) { | 592 if (it != active_downloads_.end()) { |
580 DownloadItemImpl* download = it->second; | 593 DownloadItemImpl* download = it->second; |
581 if (download->IsInProgress()) { | 594 if (download->IsInProgress()) { |
582 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | 595 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); |
583 if (delegate_) | |
584 delegate_->UpdateItemInPersistentStore(download); | |
585 } | 596 } |
586 } | 597 } |
587 } | 598 } |
588 | 599 |
589 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | 600 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, |
590 int64 size, | 601 int64 size, |
591 const std::string& hash) { | 602 const std::string& hash) { |
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
593 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 604 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
594 << " size = " << size; | 605 << " size = " << size; |
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
596 | 607 |
597 // 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 |
598 // ignore the notification. | 609 // ignore the notification. |
599 if (active_downloads_.count(download_id) == 0) | 610 if (active_downloads_.count(download_id) == 0) |
600 return; | 611 return; |
601 | 612 |
602 DownloadItemImpl* download = active_downloads_[download_id]; | 613 DownloadItemImpl* download = active_downloads_[download_id]; |
603 download->OnAllDataSaved(size, hash); | 614 download->OnAllDataSaved(size, hash); |
604 MaybeCompleteDownload(download); | 615 MaybeCompleteDownload(download); |
605 } | 616 } |
606 | 617 |
607 void DownloadManagerImpl::AssertStateConsistent( | 618 void DownloadManagerImpl::AssertStateConsistent( |
608 DownloadItemImpl* download) const { | 619 DownloadItemImpl* download) const { |
609 CHECK(ContainsKey(downloads_, download->GetId())); | 620 CHECK(ContainsKey(downloads_, download->GetId())); |
610 | 621 |
611 int64 state = download->GetState(); | 622 int64 state = download->GetState(); |
612 base::debug::Alias(&state); | 623 base::debug::Alias(&state); |
613 if (ContainsKey(active_downloads_, download->GetId())) { | |
614 if (download->IsPersisted()) | |
615 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | |
616 if (DownloadItem::IN_PROGRESS != download->GetState()) | |
617 CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle()); | |
618 } | |
619 if (DownloadItem::IN_PROGRESS == download->GetState()) | 624 if (DownloadItem::IN_PROGRESS == download->GetState()) |
620 CHECK(ContainsKey(active_downloads_, download->GetId())); | 625 CHECK(ContainsKey(active_downloads_, download->GetId())); |
621 } | 626 } |
622 | 627 |
623 bool DownloadManagerImpl::IsDownloadReadyForCompletion( | 628 bool DownloadManagerImpl::IsDownloadReadyForCompletion( |
624 DownloadItemImpl* download) { | 629 DownloadItemImpl* download) { |
625 // 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 |
626 // completion. | 631 // completion. |
627 if (!download->AllDataSaved()) | 632 if (!download->AllDataSaved()) |
628 return false; | 633 return false; |
629 | 634 |
630 // 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 |
631 // completion. | 636 // completion. |
632 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 637 if (download->GetSafetyState() == DownloadItem::DANGEROUS) |
633 return false; | 638 return false; |
634 | 639 |
635 // 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 |
636 // ready for completion. | 641 // ready for completion. |
637 if (active_downloads_.count(download->GetId()) == 0) | 642 if (active_downloads_.count(download->GetId()) == 0) |
638 return false; | 643 return false; |
639 | 644 |
640 // If the download hasn't been inserted into the history system | 645 if (download->GetTargetFilePath().DirName() != |
641 // (which occurs strictly after file name determination, intermediate | 646 download->GetFullPath().DirName()) |
642 // file rename, and UI display) then it's not ready for completion. | 647 return false; |
643 if (!download->IsPersisted()) | 648 if (download->GetTargetName().empty()) |
644 return false; | 649 return false; |
645 | 650 |
646 return true; | 651 return true; |
647 } | 652 } |
648 | 653 |
649 // When SavePackage downloads MHTML to GData (see | 654 // When SavePackage downloads MHTML to GData (see |
650 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 655 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
651 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 656 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
652 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 657 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
653 // 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... |
667 | 672 |
668 // TODO(rdsmith): DCHECK that we only pass through this point | 673 // TODO(rdsmith): DCHECK that we only pass through this point |
669 // 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 |
670 // transition on the DownloadItem. | 675 // transition on the DownloadItem. |
671 | 676 |
672 // 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; |
673 // have all data, have a history handle, (validated or safe). | 678 // have all data, have a history handle, (validated or safe). |
674 DCHECK(download->IsInProgress()); | 679 DCHECK(download->IsInProgress()); |
675 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); | 680 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); |
676 DCHECK(download->AllDataSaved()); | 681 DCHECK(download->AllDataSaved()); |
677 DCHECK(download->IsPersisted()); | |
678 | 682 |
679 // 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 |
680 // 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 |
681 // 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 |
682 // 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 |
683 // weak-ptrs. | 687 // weak-ptrs. |
684 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( | 688 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( |
685 &DownloadManagerImpl::MaybeCompleteDownloadById, | 689 &DownloadManagerImpl::MaybeCompleteDownloadById, |
686 this, download->GetId()))) | 690 this, download->GetId()))) |
687 return; | 691 return; |
688 | 692 |
689 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " | 693 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " |
690 << download->DebugString(false); | 694 << download->DebugString(false); |
691 | 695 |
692 if (delegate_) | |
693 delegate_->UpdateItemInPersistentStore(download); | |
694 download->OnDownloadCompleting(); | 696 download->OnDownloadCompleting(); |
695 } | 697 } |
696 | 698 |
697 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { | 699 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { |
698 if (ContainsKey(active_downloads_, download_id)) | 700 if (ContainsKey(active_downloads_, download_id)) |
699 MaybeCompleteDownload(active_downloads_[download_id]); | 701 MaybeCompleteDownload(active_downloads_[download_id]); |
700 } | 702 } |
701 | 703 |
702 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { | 704 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { |
703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
704 DCHECK(download); | 706 DCHECK(download); |
705 if (delegate_) | |
706 delegate_->UpdateItemInPersistentStore(download); | |
707 active_downloads_.erase(download->GetId()); | 707 active_downloads_.erase(download->GetId()); |
708 AssertStateConsistent(download); | 708 AssertStateConsistent(download); |
709 } | 709 } |
710 | 710 |
711 void DownloadManagerImpl::CancelDownload(int32 download_id) { | 711 void DownloadManagerImpl::CancelDownload(int32 download_id) { |
712 // 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 |
713 // |active_downloads_| map before we get here. | 713 // |active_downloads_| map before we get here. |
714 if (ContainsKey(active_downloads_, download_id)) | 714 if (ContainsKey(active_downloads_, download_id)) |
715 active_downloads_[download_id]->Cancel(true); | 715 active_downloads_[download_id]->Cancel(true); |
716 } | 716 } |
(...skipping 19 matching lines...) Expand all Loading... |
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
737 | 737 |
738 if (!ContainsKey(active_downloads_, download_id)) | 738 if (!ContainsKey(active_downloads_, download_id)) |
739 return; | 739 return; |
740 active_downloads_[download_id]->Interrupt(reason); | 740 active_downloads_[download_id]->Interrupt(reason); |
741 } | 741 } |
742 | 742 |
743 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 743 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
745 DCHECK(download); | 745 DCHECK(download); |
746 | 746 active_downloads_.erase(download->GetId()); |
747 // Clean up will happen when the history system create callback runs if we | |
748 // don't have a valid db_handle yet. | |
749 if (download->IsPersisted()) { | |
750 active_downloads_.erase(download->GetId()); | |
751 if (delegate_) | |
752 delegate_->UpdateItemInPersistentStore(download); | |
753 } | |
754 } | 747 } |
755 | 748 |
756 bool DownloadManagerImpl::GenerateFileHash() { | 749 bool DownloadManagerImpl::GenerateFileHash() { |
757 return delegate_ && delegate_->GenerateFileHash(); | 750 return delegate_ && delegate_->GenerateFileHash(); |
758 } | 751 } |
759 | 752 |
760 int DownloadManagerImpl::RemoveDownloadItems( | 753 int DownloadManagerImpl::RemoveDownloadItems( |
761 const DownloadItemImplVector& pending_deletes) { | 754 const DownloadItemImplVector& pending_deletes) { |
762 if (pending_deletes.empty()) | 755 if (pending_deletes.empty()) |
763 return 0; | 756 return 0; |
(...skipping 10 matching lines...) Expand all Loading... |
774 } | 767 } |
775 NotifyModelChanged(); | 768 NotifyModelChanged(); |
776 return static_cast<int>(pending_deletes.size()); | 769 return static_cast<int>(pending_deletes.size()); |
777 } | 770 } |
778 | 771 |
779 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { | 772 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { |
780 if (!download || | 773 if (!download || |
781 downloads_.find(download->GetId()) == downloads_.end()) | 774 downloads_.find(download->GetId()) == downloads_.end()) |
782 return; | 775 return; |
783 | 776 |
784 // TODO(benjhayden,rdsmith): Remove this. | |
785 if (!download->IsPersisted()) | |
786 return; | |
787 | |
788 // Make history update. | |
789 if (delegate_) | |
790 delegate_->RemoveItemFromPersistentStore(download); | |
791 | |
792 // Remove from our tables and delete. | 777 // Remove from our tables and delete. |
793 int downloads_count = | 778 int downloads_count = |
794 RemoveDownloadItems(DownloadItemImplVector(1, download)); | 779 RemoveDownloadItems(DownloadItemImplVector(1, download)); |
795 DCHECK_EQ(1, downloads_count); | 780 DCHECK_EQ(1, downloads_count); |
796 } | 781 } |
797 | 782 |
798 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, | 783 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, |
799 base::Time remove_end) { | 784 base::Time remove_end) { |
800 if (delegate_) | |
801 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); | |
802 | |
803 DownloadItemImplVector pending_deletes; | 785 DownloadItemImplVector pending_deletes; |
804 for (DownloadMap::const_iterator it = downloads_.begin(); | 786 for (DownloadMap::const_iterator it = downloads_.begin(); |
805 it != downloads_.end(); | 787 it != downloads_.end(); |
806 ++it) { | 788 ++it) { |
807 DownloadItemImpl* download = it->second; | 789 DownloadItemImpl* download = it->second; |
808 if (download->IsPersisted() && | 790 if (download->GetStartTime() >= remove_begin && |
809 download->GetStartTime() >= remove_begin && | |
810 (remove_end.is_null() || download->GetStartTime() < remove_end) && | 791 (remove_end.is_null() || download->GetStartTime() < remove_end) && |
811 (download->IsComplete() || download->IsCancelled())) { | 792 (download->IsComplete() || download->IsCancelled())) { |
812 AssertStateConsistent(download); | 793 AssertStateConsistent(download); |
813 download->NotifyRemoved(); | 794 download->NotifyRemoved(); |
814 pending_deletes.push_back(download); | 795 pending_deletes.push_back(download); |
815 } | 796 } |
816 } | 797 } |
817 return RemoveDownloadItems(pending_deletes); | 798 return RemoveDownloadItems(pending_deletes); |
818 } | 799 } |
819 | 800 |
(...skipping 26 matching lines...) Expand all Loading... |
846 // observers. | 827 // observers. |
847 observer->ModelChanged(this); | 828 observer->ModelChanged(this); |
848 } | 829 } |
849 | 830 |
850 void DownloadManagerImpl::RemoveObserver(Observer* observer) { | 831 void DownloadManagerImpl::RemoveObserver(Observer* observer) { |
851 observers_.RemoveObserver(observer); | 832 observers_.RemoveObserver(observer); |
852 } | 833 } |
853 | 834 |
854 // Operations posted to us from the history service ---------------------------- | 835 // Operations posted to us from the history service ---------------------------- |
855 | 836 |
856 // The history service has retrieved all download entries. 'entries' contains | 837 DownloadItem* DownloadManagerImpl::CreateDownloadItem( |
857 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 838 const FilePath& path, |
858 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 839 const GURL& url, |
859 std::vector<DownloadPersistentStoreInfo>* entries) { | 840 const GURL& referrer_url, |
860 history_size_ = entries->size(); | 841 const base::Time& start_time, |
861 for (size_t i = 0; i < entries->size(); ++i) { | 842 const base::Time& end_time, |
862 int64 db_handle = entries->at(i).db_handle; | 843 int64 received_bytes, |
863 base::debug::Alias(&db_handle); | 844 int64 total_bytes, |
864 | 845 DownloadItem::DownloadState state, |
865 net::BoundNetLog bound_net_log = | 846 bool opened) { |
866 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 847 DownloadItemImpl* item = factory_->CreatePersistedItem( |
867 DownloadItemImpl* download = factory_->CreatePersistedItem( | 848 this, |
868 this, GetNextId(), entries->at(i), bound_net_log); | 849 GetNextId(), |
869 DCHECK(!ContainsKey(downloads_, download->GetId())); | 850 path, |
870 downloads_[download->GetId()] = download; | 851 url, |
871 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 852 referrer_url, |
872 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 853 start_time, |
873 << " download = " << download->DebugString(true); | 854 end_time, |
874 } | 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); |
875 NotifyModelChanged(); | 864 NotifyModelChanged(); |
876 CheckForHistoryFilesRemoval(); | 865 return item; |
877 } | |
878 | |
879 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download, | |
880 int64 db_handle) { | |
881 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
882 DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle); | |
883 DCHECK(!download->IsPersisted()); | |
884 download->SetDbHandle(db_handle); | |
885 download->SetIsPersisted(); | |
886 | |
887 download_stats::RecordHistorySize(history_size_); | |
888 // Not counting |download|. | |
889 ++history_size_; | |
890 | |
891 // Show in the appropriate browser UI. | |
892 // This includes buttons to save or cancel, for a dangerous download. | |
893 ShowDownloadInBrowser(download); | |
894 | |
895 // Inform interested objects about the new download. | |
896 NotifyModelChanged(); | |
897 } | |
898 | |
899 | |
900 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, | |
901 int64 db_handle) { | |
902 // It's valid that we don't find a matching item, i.e. on shutdown. | |
903 if (!ContainsKey(downloads_, download_id)) | |
904 return; | |
905 | |
906 DownloadItemImpl* item = downloads_[download_id]; | |
907 AddDownloadItemToHistory(item, db_handle); | |
908 if (SavePageData::Get(item)) { | |
909 OnSavePageItemAddedToPersistentStore(item); | |
910 } else { | |
911 OnDownloadItemAddedToPersistentStore(item); | |
912 } | |
913 } | |
914 | |
915 // Once the new DownloadItem has been committed to the persistent store, | |
916 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), | |
917 // show it in the browser (TODO(benjhayden) the ui should observe us instead), | |
918 // and notify observers (TODO(benjhayden) observers should be able to see the | |
919 // item when it's created so they can observe it directly. Are there any | |
920 // clients that actually need to know when the item is added to the history?). | |
921 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore( | |
922 DownloadItemImpl* item) { | |
923 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
924 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle() | |
925 << " download_id = " << item->GetId() | |
926 << " download = " << item->DebugString(true); | |
927 | |
928 // If the download is still in progress, try to complete it. | |
929 // | |
930 // Otherwise, download has been cancelled or interrupted before we've | |
931 // received the DB handle. We post one final message to the history | |
932 // service so that it can be properly in sync with the DownloadItem's | |
933 // completion status, and also inform any observers so that they get | |
934 // more than just the start notification. | |
935 if (item->IsInProgress()) { | |
936 MaybeCompleteDownload(item); | |
937 } else { | |
938 DCHECK(item->IsCancelled()); | |
939 active_downloads_.erase(item->GetId()); | |
940 if (delegate_) | |
941 delegate_->UpdateItemInPersistentStore(item); | |
942 item->UpdateObservers(); | |
943 } | |
944 } | 866 } |
945 | 867 |
946 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { | 868 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { |
947 // 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 |
948 // we get this start completion event. | 870 // we get this start completion event. |
949 WebContents* content = download->GetWebContents(); | 871 WebContents* content = download->GetWebContents(); |
950 | 872 |
951 // 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 |
952 // contents. | 874 // contents. |
953 if (!content && delegate_) | 875 if (!content && delegate_) |
(...skipping 15 matching lines...) Expand all Loading... |
969 ++count; | 891 ++count; |
970 } | 892 } |
971 return count; | 893 return count; |
972 } | 894 } |
973 | 895 |
974 void DownloadManagerImpl::NotifyModelChanged() { | 896 void DownloadManagerImpl::NotifyModelChanged() { |
975 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); | 897 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); |
976 } | 898 } |
977 | 899 |
978 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { | 900 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { |
979 DownloadItem* download = GetDownload(download_id); | 901 return GetDownload(download_id); |
980 return (download && download->IsPersisted()) ? download : NULL; | |
981 } | 902 } |
982 | 903 |
983 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { | 904 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { |
984 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; | 905 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; |
985 } | 906 } |
986 | 907 |
987 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { | 908 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { |
988 if (ContainsKey(active_downloads_, download_id)) | 909 if (ContainsKey(active_downloads_, download_id)) |
989 return active_downloads_[download_id]; | 910 return active_downloads_[download_id]; |
990 return NULL; | 911 return NULL; |
(...skipping 26 matching lines...) Expand all Loading... |
1017 DownloadSet remainder; | 938 DownloadSet remainder; |
1018 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); | 939 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); |
1019 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), | 940 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), |
1020 all_downloads.begin(), all_downloads.end(), | 941 all_downloads.begin(), all_downloads.end(), |
1021 insert_it); | 942 insert_it); |
1022 DCHECK(remainder.empty()); | 943 DCHECK(remainder.empty()); |
1023 } | 944 } |
1024 #endif | 945 #endif |
1025 } | 946 } |
1026 | 947 |
1027 // SavePackage will call SavePageDownloadFinished upon completion/cancellation. | |
1028 // The history callback will call OnSavePageItemAddedToPersistentStore. | |
1029 // If the download finishes before the history callback, | |
1030 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring | |
1031 // that the history event is update regardless of the order in which these two | |
1032 // events complete. | |
1033 // If something removes the download item from the download manager (Remove, | |
1034 // Shutdown) the result will be that the SavePage system will not be able to | |
1035 // properly update the download item (which no longer exists) or the download | |
1036 // history, but the action will complete properly anyway. This may lead to the | |
1037 // history entry being wrong on a reload of chrome (specifically in the case of | |
1038 // Initiation -> History Callback -> Removal -> Completion), but there's no way | |
1039 // to solve that without canceling on Remove (which would then update the DB). | |
1040 | |
1041 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore( | |
1042 DownloadItemImpl* item) { | |
1043 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1044 | |
1045 // Finalize this download if it finished before the history callback. | |
1046 if (!item->IsInProgress()) | |
1047 SavePageDownloadFinished(item); | |
1048 } | |
1049 | |
1050 void DownloadManagerImpl::SavePageDownloadFinished( | 948 void DownloadManagerImpl::SavePageDownloadFinished( |
1051 content::DownloadItem* download) { | 949 content::DownloadItem* download) { |
1052 if (download->IsPersisted()) { | 950 if (download->IsComplete()) |
1053 if (delegate_) | 951 content::NotificationService::current()->Notify( |
1054 delegate_->UpdateItemInPersistentStore(download); | 952 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
1055 if (download->IsComplete()) | 953 content::Source<DownloadManager>(this), |
1056 content::NotificationService::current()->Notify( | 954 content::Details<DownloadItem>(download)); |
1057 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | |
1058 content::Source<DownloadManager>(this), | |
1059 content::Details<DownloadItem>(download)); | |
1060 } | |
1061 } | 955 } |
1062 | 956 |
1063 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { | 957 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { |
1064 if (delegate_) | |
1065 delegate_->UpdateItemInPersistentStore(download); | |
1066 int num_unopened = 0; | 958 int num_unopened = 0; |
1067 for (DownloadMap::iterator it = downloads_.begin(); | 959 for (DownloadMap::iterator it = downloads_.begin(); |
1068 it != downloads_.end(); ++it) { | 960 it != downloads_.end(); ++it) { |
1069 DownloadItemImpl* item = it->second; | 961 DownloadItemImpl* item = it->second; |
1070 if (item->IsComplete() && | 962 if (item->IsComplete() && |
1071 !item->GetOpened()) | 963 !item->GetOpened()) |
1072 ++num_unopened; | 964 ++num_unopened; |
1073 } | 965 } |
1074 download_stats::RecordOpensOutstanding(num_unopened); | 966 download_stats::RecordOpensOutstanding(num_unopened); |
1075 } | 967 } |
1076 | 968 |
| 969 // TODO(benjhayden) this should be a method on DI |
1077 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 970 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1078 DownloadItemImpl* download) { | 971 DownloadItemImpl* download) { |
1079 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 972 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1080 // download->GetFullPath() is only expected to be meaningful after this | 973 download->UpdateObservers(); |
1081 // callback is received. Therefore we can now add the download to a persistent | 974 MaybeCompleteDownload(download); |
1082 // store. If the rename failed, we receive an OnDownloadInterrupted() call | |
1083 // before we receive the DownloadRenamedToIntermediateName() call. | |
1084 if (delegate_) { | |
1085 delegate_->AddItemToPersistentStore(download); | |
1086 } else { | |
1087 OnItemAddedToPersistentStore(download->GetId(), | |
1088 DownloadItem::kUninitializedHandle); | |
1089 } | |
1090 } | 975 } |
1091 | 976 |
| 977 // TODO(benjhayden) this should be a method on DI |
1092 void DownloadManagerImpl::DownloadRenamedToFinalName( | 978 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1093 DownloadItemImpl* download) { | 979 DownloadItemImpl* download) { |
1094 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 980 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1095 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 981 // If the rename failed, we receive an OnDownloadInterrupted() call before we |
1096 // receive the DownloadRenamedToFinalName() call. | 982 // receive the DownloadRenamedToFinalName() call. |
1097 if (delegate_) { | 983 download->UpdateObservers(); |
1098 delegate_->UpdatePathForItemInPersistentStore( | |
1099 download, download->GetFullPath()); | |
1100 } | |
1101 } | 984 } |
OLD | NEW |