| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 "chrome/browser/download/download_manager.h" | 5 #include "chrome/browser/download/download_manager.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 state_(static_cast<DownloadState>(info.state)), | 128 state_(static_cast<DownloadState>(info.state)), |
| 129 start_time_(info.start_time), | 129 start_time_(info.start_time), |
| 130 db_handle_(info.db_handle), | 130 db_handle_(info.db_handle), |
| 131 manager_(NULL), | 131 manager_(NULL), |
| 132 is_paused_(false), | 132 is_paused_(false), |
| 133 open_when_complete_(false), | 133 open_when_complete_(false), |
| 134 safety_state_(SAFE), | 134 safety_state_(SAFE), |
| 135 auto_opened_(false), | 135 auto_opened_(false), |
| 136 original_name_(info.original_name), | 136 original_name_(info.original_name), |
| 137 render_process_id_(-1), | 137 render_process_id_(-1), |
| 138 request_id_(-1) { | 138 request_id_(-1), |
| 139 save_as_(false), |
| 140 name_finalized_(false), |
| 141 is_temporary_(false) { |
| 139 if (state_ == IN_PROGRESS) | 142 if (state_ == IN_PROGRESS) |
| 140 state_ = CANCELLED; | 143 state_ = CANCELLED; |
| 141 Init(false /* don't start progress timer */); | 144 Init(false /* don't start progress timer */); |
| 142 } | 145 } |
| 143 | 146 |
| 144 // Constructor for DownloadItem created via user action in the main thread. | 147 // Constructor for DownloadItem created via user action in the main thread. |
| 145 DownloadItem::DownloadItem(int32 download_id, | 148 DownloadItem::DownloadItem(int32 download_id, |
| 146 const FilePath& path, | 149 const FilePath& path, |
| 147 int path_uniquifier, | 150 int path_uniquifier, |
| 148 const GURL& url, | 151 const GURL& url, |
| 149 const GURL& referrer_url, | 152 const GURL& referrer_url, |
| 150 const std::string& mime_type, | 153 const std::string& mime_type, |
| 151 const FilePath& original_name, | 154 const FilePath& original_name, |
| 152 const base::Time start_time, | 155 const base::Time start_time, |
| 153 int64 download_size, | 156 int64 download_size, |
| 154 int render_process_id, | 157 int render_process_id, |
| 155 int request_id, | 158 int request_id, |
| 156 bool is_dangerous, | 159 bool is_dangerous, |
| 157 bool save_as, | 160 bool save_as, |
| 158 bool is_extension_install) | 161 bool is_extension_install, |
| 162 bool is_temporary) |
| 159 : id_(download_id), | 163 : id_(download_id), |
| 160 full_path_(path), | 164 full_path_(path), |
| 161 path_uniquifier_(path_uniquifier), | 165 path_uniquifier_(path_uniquifier), |
| 162 url_(url), | 166 url_(url), |
| 163 referrer_url_(referrer_url), | 167 referrer_url_(referrer_url), |
| 164 mime_type_(mime_type), | 168 mime_type_(mime_type), |
| 165 total_bytes_(download_size), | 169 total_bytes_(download_size), |
| 166 received_bytes_(0), | 170 received_bytes_(0), |
| 167 start_tick_(base::TimeTicks::Now()), | 171 start_tick_(base::TimeTicks::Now()), |
| 168 state_(IN_PROGRESS), | 172 state_(IN_PROGRESS), |
| 169 start_time_(start_time), | 173 start_time_(start_time), |
| 170 db_handle_(kUninitializedHandle), | 174 db_handle_(kUninitializedHandle), |
| 171 manager_(NULL), | 175 manager_(NULL), |
| 172 is_paused_(false), | 176 is_paused_(false), |
| 173 open_when_complete_(false), | 177 open_when_complete_(false), |
| 174 safety_state_(is_dangerous ? DANGEROUS : SAFE), | 178 safety_state_(is_dangerous ? DANGEROUS : SAFE), |
| 175 auto_opened_(false), | 179 auto_opened_(false), |
| 176 original_name_(original_name), | 180 original_name_(original_name), |
| 177 render_process_id_(render_process_id), | 181 render_process_id_(render_process_id), |
| 178 request_id_(request_id), | 182 request_id_(request_id), |
| 179 save_as_(save_as), | 183 save_as_(save_as), |
| 180 is_extension_install_(is_extension_install) { | 184 is_extension_install_(is_extension_install), |
| 185 name_finalized_(false), |
| 186 is_temporary_(is_temporary) { |
| 181 Init(true /* start progress timer */); | 187 Init(true /* start progress timer */); |
| 182 } | 188 } |
| 183 | 189 |
| 184 void DownloadItem::Init(bool start_timer) { | 190 void DownloadItem::Init(bool start_timer) { |
| 185 file_name_ = full_path_.BaseName(); | 191 file_name_ = full_path_.BaseName(); |
| 186 if (start_timer) | 192 if (start_timer) |
| 187 StartProgressTimer(); | 193 StartProgressTimer(); |
| 188 } | 194 } |
| 189 | 195 |
| 190 DownloadItem::~DownloadItem() { | 196 DownloadItem::~DownloadItem() { |
| 191 state_ = REMOVING; | 197 state_ = REMOVING; |
| 192 UpdateObservers(); | 198 UpdateObservers(); |
| 193 } | 199 } |
| 194 | 200 |
| 195 void DownloadItem::AddObserver(Observer* observer) { | 201 void DownloadItem::AddObserver(Observer* observer) { |
| 196 observers_.AddObserver(observer); | 202 observers_.AddObserver(observer); |
| 197 } | 203 } |
| 198 | 204 |
| 199 void DownloadItem::RemoveObserver(Observer* observer) { | 205 void DownloadItem::RemoveObserver(Observer* observer) { |
| 200 observers_.RemoveObserver(observer); | 206 observers_.RemoveObserver(observer); |
| 201 } | 207 } |
| 202 | 208 |
| 203 void DownloadItem::UpdateObservers() { | 209 void DownloadItem::UpdateObservers() { |
| 204 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this)); | 210 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this)); |
| 205 } | 211 } |
| 206 | 212 |
| 213 void DownloadItem::NotifyObserversDownloadFileCompleted() { |
| 214 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadFileCompleted(this)); |
| 215 } |
| 216 |
| 207 void DownloadItem::NotifyObserversDownloadOpened() { | 217 void DownloadItem::NotifyObserversDownloadOpened() { |
| 208 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadOpened(this)); | 218 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadOpened(this)); |
| 209 } | 219 } |
| 210 | 220 |
| 211 // If we've received more data than we were expecting (bad server info?), revert | 221 // If we've received more data than we were expecting (bad server info?), revert |
| 212 // to 'unknown size mode'. | 222 // to 'unknown size mode'. |
| 213 void DownloadItem::UpdateSize(int64 bytes_so_far) { | 223 void DownloadItem::UpdateSize(int64 bytes_so_far) { |
| 214 received_bytes_ = bytes_so_far; | 224 received_bytes_ = bytes_so_far; |
| 215 if (received_bytes_ > total_bytes_) | 225 if (received_bytes_ > total_bytes_) |
| 216 total_bytes_ = 0; | 226 total_bytes_ = 0; |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 if (hs) { | 473 if (hs) { |
| 464 HistoryService::Handle h = | 474 HistoryService::Handle h = |
| 465 hs->SearchDownloads(search_text, | 475 hs->SearchDownloads(search_text, |
| 466 &cancelable_consumer_, | 476 &cancelable_consumer_, |
| 467 NewCallback(this, | 477 NewCallback(this, |
| 468 &DownloadManager::OnSearchComplete)); | 478 &DownloadManager::OnSearchComplete)); |
| 469 cancelable_consumer_.SetClientData(hs, h, observer); | 479 cancelable_consumer_.SetClientData(hs, h, observer); |
| 470 } | 480 } |
| 471 } | 481 } |
| 472 | 482 |
| 483 void DownloadManager::GetTemporaryDownloads(Observer* observer, |
| 484 const FilePath& dir_path) { |
| 485 DCHECK(observer); |
| 486 |
| 487 std::vector<DownloadItem*> download_copy; |
| 488 |
| 489 for (DownloadMap::iterator it = downloads_.begin(); |
| 490 it != downloads_.end(); ++it) { |
| 491 if (it->second->is_temporary() && |
| 492 it->second->full_path().DirName() == dir_path) |
| 493 download_copy.push_back(it->second); |
| 494 } |
| 495 |
| 496 observer->SetDownloads(download_copy); |
| 497 } |
| 498 |
| 473 // Query the history service for information about all persisted downloads. | 499 // Query the history service for information about all persisted downloads. |
| 474 bool DownloadManager::Init(Profile* profile) { | 500 bool DownloadManager::Init(Profile* profile) { |
| 475 DCHECK(profile); | 501 DCHECK(profile); |
| 476 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 502 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
| 477 shutdown_needed_ = true; | 503 shutdown_needed_ = true; |
| 478 | 504 |
| 479 profile_ = profile; | 505 profile_ = profile; |
| 480 request_context_getter_ = profile_->GetRequestContext(); | 506 request_context_getter_ = profile_->GetRequestContext(); |
| 481 | 507 |
| 482 // 'incognito mode' will have access to past downloads, but we won't store | 508 // 'incognito mode' will have access to past downloads, but we won't store |
| (...skipping 17 matching lines...) Expand all Loading... |
| 500 DCHECK(prefs); | 526 DCHECK(prefs); |
| 501 prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL); | 527 prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL); |
| 502 | 528 |
| 503 download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); | 529 download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); |
| 504 | 530 |
| 505 // Ensure that the download directory specified in the preferences exists. | 531 // Ensure that the download directory specified in the preferences exists. |
| 506 ChromeThread::PostTask( | 532 ChromeThread::PostTask( |
| 507 ChromeThread::FILE, FROM_HERE, | 533 ChromeThread::FILE, FROM_HERE, |
| 508 NewRunnableFunction(&file_util::CreateDirectory, download_path())); | 534 NewRunnableFunction(&file_util::CreateDirectory, download_path())); |
| 509 | 535 |
| 510 // We use this to determine possibly dangerous downloads. | |
| 511 download_util::InitializeExeTypes(&exe_types_); | |
| 512 | |
| 513 // We store any file extension that should be opened automatically at | 536 // We store any file extension that should be opened automatically at |
| 514 // download completion in this pref. | 537 // download completion in this pref. |
| 515 std::wstring extensions_to_open = | 538 std::wstring extensions_to_open = |
| 516 prefs->GetString(prefs::kDownloadExtensionsToOpen); | 539 prefs->GetString(prefs::kDownloadExtensionsToOpen); |
| 517 std::vector<std::wstring> extensions; | 540 std::vector<std::wstring> extensions; |
| 518 SplitString(extensions_to_open, L':', &extensions); | 541 SplitString(extensions_to_open, L':', &extensions); |
| 519 for (size_t i = 0; i < extensions.size(); ++i) { | 542 for (size_t i = 0; i < extensions.size(); ++i) { |
| 520 if (!extensions[i].empty() && !IsExecutableFile( | 543 if (!extensions[i].empty() && !IsExecutableFile( |
| 521 FilePath::FromWStringHack(extensions[i]))) | 544 FilePath::FromWStringHack(extensions[i]))) |
| 522 auto_open_.insert(FilePath::FromWStringHack(extensions[i]).value()); | 545 auto_open_.insert(FilePath::FromWStringHack(extensions[i]).value()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // bounce around a bunch of threads and we don't want to worry about race | 579 // bounce around a bunch of threads and we don't want to worry about race |
| 557 // conditions where the user changes this pref out from under us. | 580 // conditions where the user changes this pref out from under us. |
| 558 if (*prompt_for_download_) { | 581 if (*prompt_for_download_) { |
| 559 // But never obey the preference for extension installation. Note that we | 582 // But never obey the preference for extension installation. Note that we |
| 560 // only care here about the case where an extension is installed, not when | 583 // only care here about the case where an extension is installed, not when |
| 561 // one is downloaded with "save as...". | 584 // one is downloaded with "save as...". |
| 562 if (!info->is_extension_install) | 585 if (!info->is_extension_install) |
| 563 info->save_as = true; | 586 info->save_as = true; |
| 564 } | 587 } |
| 565 | 588 |
| 566 // Determine the proper path for a download, by choosing either the default | 589 // Determine the proper path for a download, by either one of the following: |
| 567 // download directory, or prompting the user. | 590 // 1) using the provided save file path. |
| 591 // 2) using the default download directory. |
| 592 // 3) prompting the user. |
| 568 FilePath generated_name; | 593 FilePath generated_name; |
| 569 GenerateFilename(info, &generated_name); | 594 GenerateFileNameFromInfo(info, &generated_name); |
| 570 if (info->save_as && !last_download_path_.empty()) | 595 if (!info->save_file_path.empty()) |
| 596 info->suggested_path = info->save_file_path; |
| 597 else if (info->save_as && !last_download_path_.empty()) |
| 571 info->suggested_path = last_download_path_; | 598 info->suggested_path = last_download_path_; |
| 572 else | 599 else |
| 573 info->suggested_path = download_path(); | 600 info->suggested_path = download_path(); |
| 574 info->suggested_path = info->suggested_path.Append(generated_name); | 601 info->suggested_path = info->suggested_path.Append(generated_name); |
| 575 | 602 |
| 576 if (!info->save_as) { | 603 if (!info->save_as && info->save_file_path.empty()) { |
| 577 // Downloads can be marked as dangerous for two reasons: | 604 // Downloads can be marked as dangerous for two reasons: |
| 578 // a) They have a dangerous-looking filename | 605 // a) They have a dangerous-looking filename |
| 579 // b) They are an extension that is not from the gallery | 606 // b) They are an extension that is not from the gallery |
| 580 if (IsDangerous(info->suggested_path.BaseName())) | 607 if (IsDangerous(info->suggested_path.BaseName())) |
| 581 info->is_dangerous = true; | 608 info->is_dangerous = true; |
| 582 else if (info->is_extension_install && | 609 else if (info->is_extension_install && |
| 583 !ExtensionsService::IsDownloadFromGallery(info->url, | 610 !ExtensionsService::IsDownloadFromGallery(info->url, |
| 584 info->referrer_url)) { | 611 info->referrer_url)) { |
| 585 info->is_dangerous = true; | 612 info->is_dangerous = true; |
| 586 } | 613 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 info->url, | 723 info->url, |
| 697 info->referrer_url, | 724 info->referrer_url, |
| 698 info->mime_type, | 725 info->mime_type, |
| 699 info->original_name, | 726 info->original_name, |
| 700 info->start_time, | 727 info->start_time, |
| 701 info->total_bytes, | 728 info->total_bytes, |
| 702 info->child_id, | 729 info->child_id, |
| 703 info->request_id, | 730 info->request_id, |
| 704 info->is_dangerous, | 731 info->is_dangerous, |
| 705 info->save_as, | 732 info->save_as, |
| 706 info->is_extension_install); | 733 info->is_extension_install, |
| 734 !info->save_file_path.empty()); |
| 707 download->set_manager(this); | 735 download->set_manager(this); |
| 708 in_progress_[info->download_id] = download; | 736 in_progress_[info->download_id] = download; |
| 709 } else { | 737 } else { |
| 710 NOTREACHED(); // Should not exist! | 738 NOTREACHED(); // Should not exist! |
| 711 return; | 739 return; |
| 712 } | 740 } |
| 713 | 741 |
| 714 // Called before DownloadFinished in order to avoid a race condition where we | 742 // Called before DownloadFinished in order to avoid a race condition where we |
| 715 // attempt to open a completed download before it has been renamed. | 743 // attempt to open a completed download before it has been renamed. |
| 716 ChromeThread::PostTask( | 744 ChromeThread::PostTask( |
| 717 ChromeThread::FILE, FROM_HERE, | 745 ChromeThread::FILE, FROM_HERE, |
| 718 NewRunnableMethod( | 746 NewRunnableMethod( |
| 719 file_manager_, &DownloadFileManager::OnFinalDownloadName, | 747 file_manager_, &DownloadFileManager::OnFinalDownloadName, |
| 720 download->id(), target_path, this)); | 748 download->id(), target_path, this)); |
| 721 | 749 |
| 722 // If the download already completed by the time we reached this point, then | 750 // If the download already completed by the time we reached this point, then |
| 723 // notify observers that it did. | 751 // notify observers that it did. |
| 724 PendingFinishedMap::iterator pending_it = | 752 PendingFinishedMap::iterator pending_it = |
| 725 pending_finished_downloads_.find(info->download_id); | 753 pending_finished_downloads_.find(info->download_id); |
| 726 if (pending_it != pending_finished_downloads_.end()) | 754 if (pending_it != pending_finished_downloads_.end()) |
| 727 DownloadFinished(pending_it->first, pending_it->second); | 755 DownloadFinished(pending_it->first, pending_it->second); |
| 728 | 756 |
| 729 download->Rename(target_path); | 757 download->Rename(target_path); |
| 730 | 758 |
| 731 // Do not store the download in the history database for a few special cases: | 759 // Do not store the download in the history database for a few special cases: |
| 732 // - incognito mode (that is the point of this mode) | 760 // - incognito mode (that is the point of this mode) |
| 733 // - extensions (users don't think of extension installation as 'downloading') | 761 // - extensions (users don't think of extension installation as 'downloading') |
| 762 // - temporary download, like in drag-and-drop |
| 734 // We have to make sure that these handles don't collide with normal db | 763 // We have to make sure that these handles don't collide with normal db |
| 735 // handles, so we use a negative value. Eventually, they could overlap, but | 764 // handles, so we use a negative value. Eventually, they could overlap, but |
| 736 // you'd have to do enough downloading that your ISP would likely stab you in | 765 // you'd have to do enough downloading that your ISP would likely stab you in |
| 737 // the neck first. YMMV. | 766 // the neck first. YMMV. |
| 738 if (profile_->IsOffTheRecord() || download->is_extension_install()) { | 767 if (profile_->IsOffTheRecord() || download->is_extension_install() || |
| 768 download->is_temporary()) { |
| 739 static int64 fake_db_handle = kUninitializedHandle - 1; | 769 static int64 fake_db_handle = kUninitializedHandle - 1; |
| 740 OnCreateDownloadEntryComplete(*info, fake_db_handle--); | 770 OnCreateDownloadEntryComplete(*info, fake_db_handle--); |
| 741 } else { | 771 } else { |
| 742 // Update the history system with the new download. | 772 // Update the history system with the new download. |
| 743 // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong. | 773 // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong. |
| 744 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 774 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 745 if (hs) { | 775 if (hs) { |
| 746 hs->CreateDownload( | 776 hs->CreateDownload( |
| 747 *info, &cancelable_consumer_, | 777 *info, &cancelable_consumer_, |
| 748 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); | 778 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 this, &DownloadManager::ProceedWithFinishedDangerousDownload, | 871 this, &DownloadManager::ProceedWithFinishedDangerousDownload, |
| 842 download->db_handle(), | 872 download->db_handle(), |
| 843 download->full_path(), download->original_name())); | 873 download->full_path(), download->original_name())); |
| 844 return; | 874 return; |
| 845 } | 875 } |
| 846 ContinueDownloadFinished(download); | 876 ContinueDownloadFinished(download); |
| 847 } | 877 } |
| 848 | 878 |
| 849 void DownloadManager::DownloadRenamedToFinalName(int download_id, | 879 void DownloadManager::DownloadRenamedToFinalName(int download_id, |
| 850 const FilePath& full_path) { | 880 const FilePath& full_path) { |
| 881 DownloadMap::iterator it = downloads_.begin(); |
| 882 while (it != downloads_.end()) { |
| 883 DownloadItem* download = it->second; |
| 884 if (download->id() == download_id) { |
| 885 // The download file is meant to be completed if both the filename is |
| 886 // finalized and the file data is downloaded. The ordering of these two |
| 887 // actions is indeterministic. Thus, if we are still in downloading the |
| 888 // file, delay the notification. |
| 889 download->set_name_finalized(true); |
| 890 if (download->state() == DownloadItem::COMPLETE) |
| 891 download->NotifyObserversDownloadFileCompleted(); |
| 892 return; |
| 893 } |
| 894 it++; |
| 895 } |
| 851 } | 896 } |
| 852 | 897 |
| 853 void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { | 898 void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { |
| 854 // If this was a dangerous download, it has now been approved and must be | 899 // If this was a dangerous download, it has now been approved and must be |
| 855 // removed from dangerous_finished_ so it does not get deleted on shutdown. | 900 // removed from dangerous_finished_ so it does not get deleted on shutdown. |
| 856 DownloadMap::iterator it = dangerous_finished_.find(download->id()); | 901 DownloadMap::iterator it = dangerous_finished_.find(download->id()); |
| 857 if (it != dangerous_finished_.end()) | 902 if (it != dangerous_finished_.end()) |
| 858 dangerous_finished_.erase(it); | 903 dangerous_finished_.erase(it); |
| 859 | 904 |
| 860 // Handle chrome extensions explicitly and skip the shell execute. | 905 // Handle chrome extensions explicitly and skip the shell execute. |
| 861 if (download->is_extension_install()) { | 906 if (download->is_extension_install()) { |
| 862 OpenChromeExtension(download->full_path(), download->url(), | 907 OpenChromeExtension(download->full_path(), download->url(), |
| 863 download->referrer_url()); | 908 download->referrer_url()); |
| 864 download->set_auto_opened(true); | 909 download->set_auto_opened(true); |
| 865 } else if (download->open_when_complete() || | 910 } else if (download->open_when_complete() || |
| 866 ShouldOpenFileBasedOnExtension(download->full_path())) { | 911 ShouldOpenFileBasedOnExtension(download->full_path()) || |
| 867 OpenDownloadInShell(download, NULL); | 912 download->is_temporary()) { |
| 913 // If the download is temporary, like in drag-and-drop, do not open it but |
| 914 // we still need to set it auto-opened so that it can be removed from the |
| 915 // download shelf. |
| 916 if (!download->is_temporary()) |
| 917 OpenDownloadInShell(download, NULL); |
| 868 download->set_auto_opened(true); | 918 download->set_auto_opened(true); |
| 869 } | 919 } |
| 870 | 920 |
| 871 // Notify our observers that we are complete (the call to Finished() set the | 921 // Notify our observers that we are complete (the call to Finished() set the |
| 872 // state to complete but did not notify). | 922 // state to complete but did not notify). |
| 873 download->UpdateObservers(); | 923 download->UpdateObservers(); |
| 924 |
| 925 // The download file is meant to be completed if both the filename is |
| 926 // finalized and the file data is downloaded. The ordering of these two |
| 927 // actions is indeterministic. Thus, if the filename is not finalized yet, |
| 928 // delay the notification. |
| 929 if (download->name_finalized()) |
| 930 download->NotifyObserversDownloadFileCompleted(); |
| 874 } | 931 } |
| 875 | 932 |
| 876 // Called on the file thread. Renames the downloaded file to its original name. | 933 // Called on the file thread. Renames the downloaded file to its original name. |
| 877 void DownloadManager::ProceedWithFinishedDangerousDownload( | 934 void DownloadManager::ProceedWithFinishedDangerousDownload( |
| 878 int64 download_handle, | 935 int64 download_handle, |
| 879 const FilePath& path, | 936 const FilePath& path, |
| 880 const FilePath& original_name) { | 937 const FilePath& original_name) { |
| 881 bool success = false; | 938 bool success = false; |
| 882 FilePath new_path; | 939 FilePath new_path; |
| 883 int uniquifier = 0; | 940 int uniquifier = 0; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 return RemoveDownloadsBetween(base::Time(), base::Time()); | 1147 return RemoveDownloadsBetween(base::Time(), base::Time()); |
| 1091 } | 1148 } |
| 1092 | 1149 |
| 1093 // Initiate a download of a specific URL. We send the request to the | 1150 // Initiate a download of a specific URL. We send the request to the |
| 1094 // ResourceDispatcherHost, and let it send us responses like a regular | 1151 // ResourceDispatcherHost, and let it send us responses like a regular |
| 1095 // download. | 1152 // download. |
| 1096 void DownloadManager::DownloadUrl(const GURL& url, | 1153 void DownloadManager::DownloadUrl(const GURL& url, |
| 1097 const GURL& referrer, | 1154 const GURL& referrer, |
| 1098 const std::string& referrer_charset, | 1155 const std::string& referrer_charset, |
| 1099 TabContents* tab_contents) { | 1156 TabContents* tab_contents) { |
| 1157 file_manager_->DownloadUrl(url, |
| 1158 referrer, |
| 1159 referrer_charset, |
| 1160 FilePath(), |
| 1161 tab_contents->process()->id(), |
| 1162 tab_contents->render_view_host()->routing_id(), |
| 1163 request_context_getter_); |
| 1164 } |
| 1165 |
| 1166 void DownloadManager::DownloadUrlToFile(const GURL& url, |
| 1167 const GURL& referrer, |
| 1168 const std::string& referrer_charset, |
| 1169 const FilePath& save_file_path, |
| 1170 TabContents* tab_contents) { |
| 1100 DCHECK(tab_contents); | 1171 DCHECK(tab_contents); |
| 1101 file_manager_->DownloadUrl(url, | 1172 file_manager_->DownloadUrl(url, |
| 1102 referrer, | 1173 referrer, |
| 1103 referrer_charset, | 1174 referrer_charset, |
| 1175 save_file_path, |
| 1104 tab_contents->process()->id(), | 1176 tab_contents->process()->id(), |
| 1105 tab_contents->render_view_host()->routing_id(), | 1177 tab_contents->render_view_host()->routing_id(), |
| 1106 request_context_getter_); | 1178 request_context_getter_); |
| 1107 } | 1179 } |
| 1108 | 1180 |
| 1109 void DownloadManager::GenerateExtension( | 1181 void DownloadManager::GenerateExtension( |
| 1110 const FilePath& file_name, | 1182 const FilePath& file_name, |
| 1111 const std::string& mime_type, | 1183 const std::string& mime_type, |
| 1112 FilePath::StringType* generated_extension) { | 1184 FilePath::StringType* generated_extension) { |
| 1113 // We're worried about three things here: | 1185 // We're worried about three things here: |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 extension != FILE_PATH_LITERAL("gz"))) { | 1254 extension != FILE_PATH_LITERAL("gz"))) { |
| 1183 extension += FILE_PATH_LITERAL("."); | 1255 extension += FILE_PATH_LITERAL("."); |
| 1184 extension += append_extension; | 1256 extension += append_extension; |
| 1185 } | 1257 } |
| 1186 } | 1258 } |
| 1187 } | 1259 } |
| 1188 | 1260 |
| 1189 generated_extension->swap(extension); | 1261 generated_extension->swap(extension); |
| 1190 } | 1262 } |
| 1191 | 1263 |
| 1192 void DownloadManager::GenerateFilename(DownloadCreateInfo* info, | 1264 void DownloadManager::GenerateFileNameFromInfo(DownloadCreateInfo* info, |
| 1265 FilePath* generated_name) { |
| 1266 GenerateFileName(GURL(info->url), |
| 1267 info->content_disposition, |
| 1268 info->referrer_charset, |
| 1269 info->mime_type, |
| 1270 generated_name); |
| 1271 } |
| 1272 |
| 1273 void DownloadManager::GenerateFileName(const GURL& url, |
| 1274 const std::string& content_disposition, |
| 1275 const std::string& referrer_charset, |
| 1276 const std::string& mime_type, |
| 1193 FilePath* generated_name) { | 1277 FilePath* generated_name) { |
| 1194 std::wstring default_name = | 1278 std::wstring default_name = |
| 1195 l10n_util::GetString(IDS_DEFAULT_DOWNLOAD_FILENAME); | 1279 l10n_util::GetString(IDS_DEFAULT_DOWNLOAD_FILENAME); |
| 1196 #if defined(OS_WIN) | 1280 #if defined(OS_WIN) |
| 1197 FilePath default_file_path(default_name); | 1281 FilePath default_file_path(default_name); |
| 1198 #elif defined(OS_POSIX) | 1282 #elif defined(OS_POSIX) |
| 1199 FilePath default_file_path(base::SysWideToNativeMB(default_name)); | 1283 FilePath default_file_path(base::SysWideToNativeMB(default_name)); |
| 1200 #endif | 1284 #endif |
| 1201 | 1285 |
| 1202 *generated_name = net::GetSuggestedFilename(GURL(info->url), | 1286 *generated_name = net::GetSuggestedFilename(GURL(url), |
| 1203 info->content_disposition, | 1287 content_disposition, |
| 1204 info->referrer_charset, | 1288 referrer_charset, |
| 1205 default_file_path); | 1289 default_file_path); |
| 1206 | 1290 |
| 1207 DCHECK(!generated_name->empty()); | 1291 DCHECK(!generated_name->empty()); |
| 1208 | 1292 |
| 1209 GenerateSafeFilename(info->mime_type, generated_name); | 1293 GenerateSafeFileName(mime_type, generated_name); |
| 1210 } | 1294 } |
| 1211 | 1295 |
| 1212 void DownloadManager::AddObserver(Observer* observer) { | 1296 void DownloadManager::AddObserver(Observer* observer) { |
| 1213 observers_.AddObserver(observer); | 1297 observers_.AddObserver(observer); |
| 1214 observer->ModelChanged(); | 1298 observer->ModelChanged(); |
| 1215 } | 1299 } |
| 1216 | 1300 |
| 1217 void DownloadManager::RemoveObserver(Observer* observer) { | 1301 void DownloadManager::RemoveObserver(Observer* observer) { |
| 1218 observers_.RemoveObserver(observer); | 1302 observers_.RemoveObserver(observer); |
| 1219 } | 1303 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 } | 1440 } |
| 1357 // We consider only other application types to be executable. | 1441 // We consider only other application types to be executable. |
| 1358 return net::MatchesMimeType("application/*", mime_type); | 1442 return net::MatchesMimeType("application/*", mime_type); |
| 1359 } | 1443 } |
| 1360 | 1444 |
| 1361 bool DownloadManager::IsExecutableFile(const FilePath& path) const { | 1445 bool DownloadManager::IsExecutableFile(const FilePath& path) const { |
| 1362 return IsExecutableExtension(path.Extension()); | 1446 return IsExecutableExtension(path.Extension()); |
| 1363 } | 1447 } |
| 1364 | 1448 |
| 1365 bool DownloadManager::IsExecutableExtension( | 1449 bool DownloadManager::IsExecutableExtension( |
| 1366 const FilePath::StringType& extension) const { | 1450 const FilePath::StringType& extension) { |
| 1367 if (extension.empty()) | 1451 if (extension.empty()) |
| 1368 return false; | 1452 return false; |
| 1369 if (!IsStringASCII(extension)) | 1453 if (!IsStringASCII(extension)) |
| 1370 return false; | 1454 return false; |
| 1371 #if defined(OS_WIN) | 1455 #if defined(OS_WIN) |
| 1372 std::string ascii_extension = WideToASCII(extension); | 1456 std::string ascii_extension = WideToASCII(extension); |
| 1373 #elif defined(OS_POSIX) | 1457 #elif defined(OS_POSIX) |
| 1374 std::string ascii_extension = extension; | 1458 std::string ascii_extension = extension; |
| 1375 #endif | 1459 #endif |
| 1376 StringToLowerASCII(&ascii_extension); | |
| 1377 | 1460 |
| 1378 // Strip out leading dot if it's still there | 1461 // Strip out leading dot if it's still there |
| 1379 if (ascii_extension[0] == FilePath::kExtensionSeparator) | 1462 if (ascii_extension[0] == FilePath::kExtensionSeparator) |
| 1380 ascii_extension.erase(0, 1); | 1463 ascii_extension.erase(0, 1); |
| 1381 | 1464 |
| 1382 return exe_types_.find(ascii_extension) != exe_types_.end(); | 1465 return download_util::IsExecutableExtension(ascii_extension); |
| 1383 } | 1466 } |
| 1384 | 1467 |
| 1385 void DownloadManager::ResetAutoOpenFiles() { | 1468 void DownloadManager::ResetAutoOpenFiles() { |
| 1386 auto_open_.clear(); | 1469 auto_open_.clear(); |
| 1387 SaveAutoOpens(); | 1470 SaveAutoOpens(); |
| 1388 } | 1471 } |
| 1389 | 1472 |
| 1390 bool DownloadManager::HasAutoOpenFileTypesRegistered() const { | 1473 bool DownloadManager::HasAutoOpenFileTypesRegistered() const { |
| 1391 return !auto_open_.empty(); | 1474 return !auto_open_.empty(); |
| 1392 } | 1475 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 return; | 1531 return; |
| 1449 | 1532 |
| 1450 ChromeThread::PostTask( | 1533 ChromeThread::PostTask( |
| 1451 ChromeThread::FILE, FROM_HERE, | 1534 ChromeThread::FILE, FROM_HERE, |
| 1452 NewRunnableMethod( | 1535 NewRunnableMethod( |
| 1453 this, &DownloadManager::ProceedWithFinishedDangerousDownload, | 1536 this, &DownloadManager::ProceedWithFinishedDangerousDownload, |
| 1454 download->db_handle(), download->full_path(), | 1537 download->db_handle(), download->full_path(), |
| 1455 download->original_name())); | 1538 download->original_name())); |
| 1456 } | 1539 } |
| 1457 | 1540 |
| 1458 void DownloadManager::GenerateSafeFilename(const std::string& mime_type, | 1541 void DownloadManager::GenerateSafeFileName(const std::string& mime_type, |
| 1459 FilePath* file_name) { | 1542 FilePath* file_name) { |
| 1460 // Make sure we get the right file extension | 1543 // Make sure we get the right file extension |
| 1461 FilePath::StringType extension; | 1544 FilePath::StringType extension; |
| 1462 GenerateExtension(*file_name, mime_type, &extension); | 1545 GenerateExtension(*file_name, mime_type, &extension); |
| 1463 file_util::ReplaceExtension(file_name, extension); | 1546 file_util::ReplaceExtension(file_name, extension); |
| 1464 | 1547 |
| 1465 #if defined(OS_WIN) | 1548 #if defined(OS_WIN) |
| 1466 // Prepend "_" to the file name if it's a reserved name | 1549 // Prepend "_" to the file name if it's a reserved name |
| 1467 FilePath::StringType leaf_name = file_name->BaseName().value(); | 1550 FilePath::StringType leaf_name = file_name->BaseName().value(); |
| 1468 DCHECK(!leaf_name.empty()); | 1551 DCHECK(!leaf_name.empty()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 | 1648 |
| 1566 if (contents) | 1649 if (contents) |
| 1567 contents->OnStartDownload(download); | 1650 contents->OnStartDownload(download); |
| 1568 } | 1651 } |
| 1569 | 1652 |
| 1570 // Clears the last download path, used to initialize "save as" dialogs. | 1653 // Clears the last download path, used to initialize "save as" dialogs. |
| 1571 void DownloadManager::ClearLastDownloadPath() { | 1654 void DownloadManager::ClearLastDownloadPath() { |
| 1572 last_download_path_ = FilePath(); | 1655 last_download_path_ = FilePath(); |
| 1573 } | 1656 } |
| 1574 | 1657 |
| OLD | NEW |