diff options
Diffstat (limited to 'chrome/browser/download')
| -rw-r--r-- | chrome/browser/download/download_file_manager.cc | 15 | ||||
| -rw-r--r-- | chrome/browser/download/download_item.cc | 51 | ||||
| -rw-r--r-- | chrome/browser/download/download_item.h | 39 | ||||
| -rw-r--r-- | chrome/browser/download/download_manager.cc | 40 | ||||
| -rw-r--r-- | chrome/browser/download/download_manager.h | 3 | ||||
| -rw-r--r-- | chrome/browser/download/download_prefs.cc | 8 | ||||
| -rw-r--r-- | chrome/browser/download/download_prefs.h | 4 | ||||
| -rw-r--r-- | chrome/browser/download/download_uitest.cc | 2 | ||||
| -rw-r--r-- | chrome/browser/download/download_util.cc | 25 | ||||
| -rw-r--r-- | chrome/browser/download/save_file_manager.cc | 7 | ||||
| -rw-r--r-- | chrome/browser/download/save_file_manager.h | 8 | ||||
| -rw-r--r-- | chrome/browser/download/save_package.cc | 169 | ||||
| -rw-r--r-- | chrome/browser/download/save_package.h | 17 | ||||
| -rw-r--r-- | chrome/browser/download/save_package_unittest.cc | 42 | ||||
| -rw-r--r-- | chrome/browser/download/save_page_browsertest.cc | 2 | ||||
| -rw-r--r-- | chrome/browser/download/save_page_uitest.cc | 2 |
16 files changed, 203 insertions, 231 deletions
diff --git a/chrome/browser/download/download_file_manager.cc b/chrome/browser/download/download_file_manager.cc index 8415c87..86346a8 100644 --- a/chrome/browser/download/download_file_manager.cc +++ b/chrome/browser/download/download_file_manager.cc @@ -176,7 +176,7 @@ void DownloadFileManager::StartDownload(DownloadCreateInfo* info) { BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile, - info, manager)); + info, make_scoped_refptr(manager))); } // We don't forward an update to the UI thread here, since we want to throttle @@ -286,7 +286,7 @@ void DownloadFileManager::OnIntermediateDownloadName( return; DownloadFile* download = it->second; - if (!download->Rename(full_path, false)) { + if (!download->Rename(full_path, false /* is_final_rename */)) { // Error. Between the time the UI thread generated 'full_path' to the time // this code runs, something happened that prevents us from renaming. CancelDownloadOnRename(id); @@ -303,17 +303,16 @@ void DownloadFileManager::OnIntermediateDownloadName( // 1. tmp -> foo (need_delete_crdownload=T) // 2. foo.crdownload -> foo (need_delete_crdownload=F) // 3. tmp-> unconfirmed.xxx.crdownload (need_delete_crdownload=F) -void DownloadFileManager::OnFinalDownloadName(int id, - const FilePath& full_path, - bool need_delete_crdownload, - DownloadManager* manager) { +void DownloadFileManager::OnFinalDownloadName( + int id, const FilePath& full_path, bool need_delete_crdownload, + DownloadManager* download_manager) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); DownloadFile* download = GetDownloadFile(id); if (!download) return; - if (download->Rename(full_path, true)) { + if (download->Rename(full_path, true /* is_final_rename */)) { #if defined(OS_MACOSX) // Done here because we only want to do this once; see // http://crbug.com/13120 for details. @@ -322,7 +321,7 @@ void DownloadFileManager::OnFinalDownloadName(int id, BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod( - manager, &DownloadManager::DownloadRenamedToFinalName, id, + download_manager, &DownloadManager::DownloadRenamedToFinalName, id, full_path)); } else { // Error. Between the time the UI thread generated 'full_path' to the time diff --git a/chrome/browser/download/download_item.cc b/chrome/browser/download/download_item.cc index df5edcc..7b4b134 100644 --- a/chrome/browser/download/download_item.cc +++ b/chrome/browser/download/download_item.cc @@ -42,6 +42,7 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, const DownloadCreateInfo& info) : id_(-1), full_path_(info.path), + path_uniquifier_(0), url_(info.url), referrer_url_(info.referrer_url), mime_type_(info.mime_type), @@ -57,7 +58,7 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, open_when_complete_(false), safety_state_(SAFE), auto_opened_(false), - original_name_(info.original_name), + target_name_(info.original_name), render_process_id_(-1), request_id_(-1), save_as_(false), @@ -65,7 +66,6 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, is_extension_install_(info.is_extension_install), name_finalized_(false), is_temporary_(false), - need_final_rename_(false), opened_(false) { if (state_ == IN_PROGRESS) state_ = CANCELLED; @@ -94,7 +94,7 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, open_when_complete_(false), safety_state_(info.is_dangerous ? DANGEROUS : SAFE), auto_opened_(false), - original_name_(info.original_name), + target_name_(info.original_name), render_process_id_(info.child_id), request_id_(info.request_id), save_as_(info.prompt_user_for_save_location), @@ -102,7 +102,6 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, is_extension_install_(info.is_extension_install), name_finalized_(false), is_temporary_(!info.save_info.file_path.empty()), - need_final_rename_(false), opened_(false) { Init(true /* start progress timer */); } @@ -130,7 +129,6 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, open_when_complete_(false), safety_state_(SAFE), auto_opened_(false), - original_name_(FilePath()), render_process_id_(-1), request_id_(-1), save_as_(false), @@ -138,7 +136,6 @@ DownloadItem::DownloadItem(DownloadManager* download_manager, is_extension_install_(false), name_finalized_(false), is_temporary_(false), - need_final_rename_(false), opened_(false) { Init(true /* start progress timer */); } @@ -165,24 +162,21 @@ void DownloadItem::NotifyObserversDownloadFileCompleted() { } bool DownloadItem::CanOpenDownload() { - FilePath file_to_use = full_path(); - if (!original_name().value().empty()) - file_to_use = original_name(); - - return !Extension::IsExtension(file_to_use) && - !download_util::IsExecutableFile(file_to_use); + return !Extension::IsExtension(target_name_) && + !download_util::IsExecutableFile(target_name_); } bool DownloadItem::ShouldOpenFileBasedOnExtension() { - return download_manager_->ShouldOpenFileBasedOnExtension(full_path()); + return download_manager_->ShouldOpenFileBasedOnExtension( + GetUserVerifiedFileName()); } void DownloadItem::OpenFilesBasedOnExtension(bool open) { DownloadPrefs* prefs = download_manager_->download_prefs(); if (open) - prefs->EnableAutoOpenBasedOnExtension(full_path()); + prefs->EnableAutoOpenBasedOnExtension(GetUserVerifiedFileName()); else - prefs->DisableAutoOpenBasedOnExtension(full_path()); + prefs->DisableAutoOpenBasedOnExtension(GetUserVerifiedFileName()); } void DownloadItem::OpenDownload() { @@ -281,7 +275,8 @@ void DownloadItem::Finished() { *this); auto_opened_ = true; } else if (open_when_complete() || - download_manager_->ShouldOpenFileBasedOnExtension(full_path()) || + download_manager_->ShouldOpenFileBasedOnExtension( + GetUserVerifiedFileName()) || is_temporary()) { // If the download is temporary, like in drag-and-drop, do not open it but // we still need to set it auto-opened so that it can be removed from the @@ -344,7 +339,6 @@ int DownloadItem::PercentComplete() const { void DownloadItem::Rename(const FilePath& full_path) { DCHECK(!full_path.empty()); full_path_ = full_path; - file_name_ = full_path_.BaseName(); } void DownloadItem::TogglePause() { @@ -386,26 +380,35 @@ bool DownloadItem::MatchesQuery(const string16& query) const { if (url_formatted.find(query) != string16::npos) return true; - string16 path(l10n_util::ToLower(WideToUTF16(full_path_.ToWStringHack()))); + string16 path(l10n_util::ToLower(WideToUTF16(full_path().ToWStringHack()))); if (path.find(query) != std::wstring::npos) return true; return false; } -FilePath DownloadItem::GetFileName() const { - if (safety_state_ == DownloadItem::SAFE) - return file_name_; +FilePath DownloadItem::GetTargetFilePath() const { + return full_path_.DirName().Append(target_name_); +} + +FilePath DownloadItem::GetFileNameToReportUser() const { if (path_uniquifier_ > 0) { - FilePath name(original_name_); + FilePath name(target_name_); download_util::AppendNumberToPath(&name, path_uniquifier_); return name; } - return original_name_; + return target_name_; +} + +FilePath DownloadItem::GetUserVerifiedFileName() const { + if (safety_state_ == DownloadItem::SAFE) + return target_name_; + return full_path_.BaseName(); } void DownloadItem::Init(bool start_timer) { - file_name_ = full_path_.BaseName(); + if (target_name_.value().empty()) + target_name_ = full_path_.BaseName(); if (start_timer) StartProgressTimer(); } diff --git a/chrome/browser/download/download_item.h b/chrome/browser/download/download_item.h index 3431bc7..4bc2b39 100644 --- a/chrome/browser/download/download_item.h +++ b/chrome/browser/download/download_item.h @@ -187,23 +187,31 @@ class DownloadItem { safety_state_ = safety_state; } bool auto_opened() { return auto_opened_; } - FilePath original_name() const { return original_name_; } + FilePath target_name() const { return target_name_; } bool save_as() const { return save_as_; } bool is_otr() const { return is_otr_; } bool is_extension_install() const { return is_extension_install_; } bool name_finalized() const { return name_finalized_; } bool is_temporary() const { return is_temporary_; } - bool need_final_rename() const { return need_final_rename_; } - void set_need_final_rename(bool need_final_rename) { - need_final_rename_ = need_final_rename; - } void set_opened(bool opened) { opened_ = opened; } bool opened() const { return opened_; } + // Returns the final target file path for the download. + FilePath GetTargetFilePath() const; + // Returns the file-name that should be reported to the user, which is - // file_name_ for safe downloads and original_name_ for dangerous ones with - // the uniquifier number. - FilePath GetFileName() const; + // target_name_ possibly with the uniquifier number. + FilePath GetFileNameToReportUser() const; + + // Returns the user-verified target name for the download. + // This returns the same path as target_name() for safe downloads + // but does not for dangerous downloads until the name is verified. + FilePath GetUserVerifiedFileName() const; + + // Returns true if the current file name is not the final target name yet. + bool NeedsRename() const { + return target_name_ != full_path_.BaseName(); + } private: void Init(bool start_timer); @@ -218,16 +226,13 @@ class DownloadItem { // Request ID assigned by the ResourceDispatcherHost. int32 id_; - // Full path to the downloaded file + // Full path to the downloaded or downloading file. FilePath full_path_; // A number that should be appended to the path to make it unique, or 0 if the // path should be used as is. int path_uniquifier_; - // Short display version of the file - FilePath file_name_; - // The URL from whence we came. GURL url_; @@ -283,9 +288,10 @@ class DownloadItem { // before the observer is added. bool auto_opened_; - // Dangerous download are given temporary names until the user approves them. - // This stores their original name. - FilePath original_name_; + // Dangerous downloads or ongoing downloads are given temporary names until + // the user approves them or the downloads finish. + // This stores their final target name. + FilePath target_name_; // For canceling or pausing requests. int render_process_id_; @@ -306,9 +312,6 @@ class DownloadItem { // True if the item was downloaded temporarily. bool is_temporary_; - // True if the file needs final rename. - bool need_final_rename_; - // Did the user open the item either directly or indirectly (such as by // setting always open files of this type)? The shelf also sets this field // when the user closes the shelf before the item has been opened but should diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 106c8fc..59476b4 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -12,6 +12,7 @@ #include "base/path_service.h" #include "base/rand_util.h" #include "base/stl_util-inl.h" +#include "base/stringprintf.h" #include "base/sys_string_conversions.h" #include "base/task.h" #include "base/utf_string_conversions.h" @@ -136,6 +137,8 @@ void DownloadManager::Shutdown() { download_history_.reset(); + request_context_getter_ = NULL; + shutdown_needed_ = false; } @@ -339,8 +342,10 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info, FilePath::StringType file_name; FilePath path; while (path.empty()) { - SStringPrintf(&file_name, FILE_PATH_LITERAL("unconfirmed %d.crdownload"), - base::RandInt(0, 100000)); + base::SStringPrintf( + &file_name, + FILE_PATH_LITERAL("unconfirmed %d.crdownload"), + base::RandInt(0, 100000)); path = dir.Append(file_name); if (file_util::PathExists(path)) path = FilePath(); @@ -448,7 +453,7 @@ void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info, NewRunnableMethod( file_manager_, &DownloadFileManager::OnIntermediateDownloadName, download->id(), download_path, this)); - download->set_need_final_rename(true); + download->Rename(download_path); } if (download_finished) { @@ -458,8 +463,6 @@ void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info, pending_finished_downloads_[info->download_id]); } - download->Rename(target_path); - download_history_->AddEntry(*info, download, NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); @@ -524,16 +527,16 @@ void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { NewRunnableMethod( this, &DownloadManager::ProceedWithFinishedDangerousDownload, download->db_handle(), - download->full_path(), download->original_name())); + download->full_path(), download->target_name())); return; } - if (download->need_final_rename()) { + if (download->NeedsRename()) { BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, NewRunnableMethod( file_manager_, &DownloadFileManager::OnFinalDownloadName, - download->id(), download->full_path(), false, this)); + download->id(), download->GetTargetFilePath(), false, this)); return; } @@ -543,16 +546,18 @@ void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { void DownloadManager::DownloadRenamedToFinalName(int download_id, const FilePath& full_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DownloadItem* item = GetDownloadItem(download_id); if (!item) return; + + bool needed_rename = item->NeedsRename(); + item->Rename(full_path); + item->OnNameFinalized(); - // This was called from DownloadFinished; continue to call - // ContinueDownloadFinished. - if (item->need_final_rename()) { - item->set_need_final_rename(false); + if (needed_rename) { + // This was called from OnAllDataSaved; continue to call + // ContinueDownloadFinished. ContinueDownloadFinished(item); } } @@ -611,7 +616,7 @@ void DownloadManager::DangerousDownloadRenamed(int64 download_handle, // If we failed to rename the file, we'll just keep the name as is. if (success) { // We need to update the path uniquifier so that the UI shows the right - // name when calling GetFileName(). + // name when calling GetFileNameToReportUser(). download->set_path_uniquifier(new_path_uniquifier); RenameDownload(download, new_path); } @@ -892,7 +897,7 @@ void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { NewRunnableMethod( this, &DownloadManager::ProceedWithFinishedDangerousDownload, download->db_handle(), download->full_path(), - download->original_name())); + download->target_name())); } // Operations posted to us from the history service ---------------------------- @@ -912,8 +917,9 @@ void DownloadManager::OnQueryDownloadEntriesComplete( // Once the new DownloadItem's creation info has been committed to the history // service, we associate the DownloadItem with the db handle, update our // 'downloads_' map and inform observers. -void DownloadManager::OnCreateDownloadEntryComplete(DownloadCreateInfo info, - int64 db_handle) { +void DownloadManager::OnCreateDownloadEntryComplete( + const DownloadCreateInfo& info, + int64 db_handle) { DownloadMap::iterator it = in_progress_.find(info.download_id); DCHECK(it != in_progress_.end()); diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h index 56acb00..6608af2 100644 --- a/chrome/browser/download/download_manager.h +++ b/chrome/browser/download/download_manager.h @@ -167,7 +167,8 @@ class DownloadManager // Methods called on completion of a query sent to the history system. void OnQueryDownloadEntriesComplete( std::vector<DownloadCreateInfo>* entries); - void OnCreateDownloadEntryComplete(DownloadCreateInfo info, int64 db_handle); + void OnCreateDownloadEntryComplete( + const DownloadCreateInfo& info, int64 db_handle); // Display a new download in the appropriate browser UI. void ShowDownloadInBrowser(const DownloadCreateInfo& info, diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc index b8645db..8673e0a 100644 --- a/chrome/browser/download/download_prefs.cc +++ b/chrome/browser/download/download_prefs.cc @@ -81,8 +81,8 @@ bool DownloadPrefs::IsAutoOpenEnabledForExtension( return auto_open_.find(extension) != auto_open_.end(); } -bool DownloadPrefs::EnableAutoOpenBasedOnExtension(const FilePath& file_path) { - FilePath::StringType extension = file_path.Extension(); +bool DownloadPrefs::EnableAutoOpenBasedOnExtension(const FilePath& file_name) { + FilePath::StringType extension = file_name.Extension(); if (extension.empty()) return false; DCHECK(extension[0] == FilePath::kExtensionSeparator); @@ -95,8 +95,8 @@ bool DownloadPrefs::EnableAutoOpenBasedOnExtension(const FilePath& file_path) { return true; } -void DownloadPrefs::DisableAutoOpenBasedOnExtension(const FilePath& file_path) { - FilePath::StringType extension = file_path.Extension(); +void DownloadPrefs::DisableAutoOpenBasedOnExtension(const FilePath& file_name) { + FilePath::StringType extension = file_name.Extension(); if (extension.empty()) return; DCHECK(extension[0] == FilePath::kExtensionSeparator); diff --git a/chrome/browser/download/download_prefs.h b/chrome/browser/download/download_prefs.h index bc8a9f3..1345a44 100644 --- a/chrome/browser/download/download_prefs.h +++ b/chrome/browser/download/download_prefs.h @@ -33,10 +33,10 @@ class DownloadPrefs { // Enables auto-open based on file extension. Returns true on success. // TODO(phajdan.jr): Add WARN_UNUSED_RESULT here. - bool EnableAutoOpenBasedOnExtension(const FilePath& file_path); + bool EnableAutoOpenBasedOnExtension(const FilePath& file_name); // Disables auto-open based on file extension. - void DisableAutoOpenBasedOnExtension(const FilePath& file_path); + void DisableAutoOpenBasedOnExtension(const FilePath& file_name); void ResetToDefaults(); void ResetAutoOpen(); diff --git a/chrome/browser/download/download_uitest.cc b/chrome/browser/download/download_uitest.cc index 16db455..f5bae1f 100644 --- a/chrome/browser/download/download_uitest.cc +++ b/chrome/browser/download/download_uitest.cc @@ -16,7 +16,7 @@ #include "base/platform_thread.h" #include "base/string_util.h" #include "base/test/test_file_util.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/net/url_request_mock_http_job.h" #include "chrome/browser/net/url_request_slow_download_job.h" #include "chrome/common/chrome_constants.h" diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index affa24a..1235285 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -20,7 +20,9 @@ #include "base/singleton.h" #include "base/string16.h" #include "base/string_number_conversions.h" +#include "base/stringprintf.h" #include "base/sys_string_conversions.h" +#include "base/thread_restrictions.h" #include "base/utf_string_conversions.h" #include "base/values.h" #include "base/win/windows_version.h" @@ -150,8 +152,13 @@ void GenerateExtension(const FilePath& file_name, extension.assign(default_extension); #endif - if (extension.empty()) + if (extension.empty()) { + // The GetPreferredExtensionForMimeType call will end up going to disk. Do + // this on another thread to avoid slowing the IO thread. + // http://crbug.com/61827 + base::ThreadRestrictions::ScopedAllowIO allow_io; net::GetPreferredExtensionForMimeType(mime_type, &extension); + } generated_extension->swap(extension); } @@ -442,8 +449,8 @@ void DragDownload(const DownloadItem* download, OSExchangeData data; if (icon) { - drag_utils::CreateDragImageForFile(download->GetFileName().value(), icon, - &data); + drag_utils::CreateDragImageForFile( + download->GetFileNameToReportUser().value(), icon, &data); } const FilePath full_path = download->full_path(); @@ -456,7 +463,7 @@ void DragDownload(const DownloadItem* download, // Add URL so that we can load supported files when dragged to TabContents. if (net::IsSupportedMimeType(mime_type)) { data.SetURL(GURL(WideToUTF8(full_path.ToWStringHack())), - download->GetFileName().ToWStringHack()); + download->GetFileNameToReportUser().ToWStringHack()); } #if defined(OS_WIN) @@ -496,10 +503,10 @@ DictionaryValue* CreateDownloadItemValue(DownloadItem* download, int id) { WideToUTF16Hack(base::TimeFormatShortDate(download->start_time()))); file_value->SetInteger("id", id); file_value->SetString("file_path", - WideToUTF16Hack(download->full_path().ToWStringHack())); + WideToUTF16Hack(download->GetTargetFilePath().ToWStringHack())); // Keep file names as LTR. string16 file_name = WideToUTF16Hack( - download->GetFileName().ToWStringHack()); + download->GetFileNameToReportUser().ToWStringHack()); file_name = base::i18n::GetDisplayStringInLTRDirectionality(file_name); file_value->SetString("file_name", file_name); file_value->SetString("url", download->url().spec()); @@ -709,8 +716,10 @@ int GetUniquePathNumberWithCrDownload(const FilePath& path) { FilePath GetCrDownloadPath(const FilePath& suggested_path) { FilePath::StringType file_name; - SStringPrintf(&file_name, PRFilePathLiteral FILE_PATH_LITERAL(".crdownload"), - suggested_path.value().c_str()); + base::SStringPrintf( + &file_name, + PRFilePathLiteral FILE_PATH_LITERAL(".crdownload"), + suggested_path.value().c_str()); return FilePath(file_name); } diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc index 3cc3daf..2c432a7 100644 --- a/chrome/browser/download/save_file_manager.cc +++ b/chrome/browser/download/save_file_manager.cc @@ -138,7 +138,7 @@ void SaveFileManager::SaveURL(const GURL& url, referrer, render_process_host_id, render_view_id, - request_context_getter)); + make_scoped_refptr(request_context_getter))); } else { // We manually start the save job. SaveFileCreateInfo* info = new SaveFileCreateInfo(file_full_path, @@ -250,7 +250,6 @@ void SaveFileManager::UpdateSaveProgress(int save_id, this, &SaveFileManager::OnUpdateSaveProgress, save_file->save_id(), save_file->bytes_so_far(), write_success)); } - data->Release(); } // The IO thread will call this when saving is completed or it got error when @@ -260,7 +259,7 @@ void SaveFileManager::UpdateSaveProgress(int save_id, // thread, which will use the save URL to find corresponding request record and // delete it. void SaveFileManager::SaveFinished(int save_id, - GURL save_url, + const GURL& save_url, int render_process_id, bool is_success) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); @@ -339,7 +338,7 @@ void SaveFileManager::OnSaveFinished(int save_id, package->SaveFinished(save_id, bytes_so_far, is_success); } -void SaveFileManager::OnErrorFinished(GURL save_url, int tab_id) { +void SaveFileManager::OnErrorFinished(const GURL& save_url, int tab_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); SavePackage* save_package = UnregisterStartingRequest(save_url, tab_id); if (save_package) diff --git a/chrome/browser/download/save_file_manager.h b/chrome/browser/download/save_file_manager.h index 4b13acb..207d91e 100644 --- a/chrome/browser/download/save_file_manager.h +++ b/chrome/browser/download/save_file_manager.h @@ -102,8 +102,10 @@ class SaveFileManager // Notifications sent from the IO thread and run on the file thread: void StartSave(SaveFileCreateInfo* info); void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size); - void SaveFinished(int save_id, GURL save_url, - int render_process_id, bool is_success); + void SaveFinished(int save_id, + const GURL& save_url, + int render_process_id, + bool is_success); // Notifications sent from the UI thread and run on the file thread. // Cancel a SaveFile instance which has specified save id. @@ -190,7 +192,7 @@ class SaveFileManager void OnSaveFinished(int save_id, int64 bytes_so_far, bool is_success); // For those requests that do not have valid save id, use // map:(url, SavePackage) to find the request and remove it. - void OnErrorFinished(GURL save_url, int tab_id); + void OnErrorFinished(const GURL& save_url, int tab_id); // Notifies SavePackage that the whole page saving job is finished. void OnFinishSavePageJob(int render_process_id, int render_view_id, diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index a148f18..69cbed1 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -53,24 +53,6 @@ using base::Time; using WebKit::WebPageSerializerClient; -// This structure is for storing parameters which we will use to create a -// SavePackage object later. -struct SavePackageParam { - // MIME type of current tab contents. - const std::string current_tab_mime_type; - // Pointer to preference service. - SavePackage::SavePackageType save_type; - // File path for main html file. - FilePath saved_main_file_path; - // Directory path for saving sub resources and sub html frames. - FilePath dir; - - explicit SavePackageParam(const std::string& mime_type) - : current_tab_mime_type(mime_type), - save_type(SavePackage::SAVE_TYPE_UNKNOWN) { - } -}; - namespace { // A counter for uniquely identifying each save package. @@ -183,46 +165,6 @@ bool GetSafePureFileName(const FilePath& dir_path, return false; } -// This task creates a directory (if needed) and then posts a task on the given -// thread. -class CreateDownloadDirectoryTask : public Task { - public: - CreateDownloadDirectoryTask(SavePackage* save_package, - const FilePath& default_save_file_dir, - const FilePath& default_download_dir) - : save_package_(save_package), - default_save_file_dir_(default_save_file_dir), - default_download_dir_(default_download_dir){ - } - - virtual void Run() { - // If the default html/websites save folder doesn't exist... - if (!file_util::DirectoryExists(default_save_file_dir_)) { - // If the default download dir doesn't exist, create it. - if (!file_util::DirectoryExists(default_download_dir_)) - file_util::CreateDirectory(default_download_dir_); - - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - NewRunnableMethod(save_package_, - &SavePackage::ContinueGetSaveInfo, - default_download_dir_)); - } else { - // If it does exist, use the default save dir param. - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - NewRunnableMethod(save_package_, - &SavePackage::ContinueGetSaveInfo, - default_save_file_dir_)); - } - } - - private: - SavePackage* save_package_; - FilePath default_save_file_dir_; - FilePath default_download_dir_; - - DISALLOW_COPY_AND_ASSIGN(CreateDownloadDirectoryTask); -}; - } // namespace SavePackage::SavePackage(TabContents* tab_contents, @@ -1025,8 +967,7 @@ void SavePackage::OnReceivedSerializedHtmlData(const GURL& frame_url, if (!data.empty()) { // Prepare buffer for saving HTML data. - net::IOBuffer* new_data = new net::IOBuffer(data.size()); - new_data->AddRef(); // We'll pass the buffer to SaveFileManager. + scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size())); memcpy(new_data->data(), data.data(), data.size()); // Call write file functionality in file thread. @@ -1114,7 +1055,7 @@ void SavePackage::SetShouldPromptUser(bool should_prompt) { FilePath SavePackage::GetSuggestedNameForSaveAs( bool can_save_as_complete, - const FilePath::StringType& contents_mime_type) { + const std::string& contents_mime_type) { FilePath name_with_proper_ext = FilePath::FromWStringHack(UTF16ToWideHack(title_)); @@ -1174,7 +1115,7 @@ FilePath SavePackage::EnsureHtmlExtension(const FilePath& name) { } FilePath SavePackage::EnsureMimeExtension(const FilePath& name, - const FilePath::StringType& contents_mime_type) { + const std::string& contents_mime_type) { // Start extension at 1 to skip over period if non-empty. FilePath::StringType ext = name.Extension().length() ? name.Extension().substr(1) : name.Extension(); @@ -1191,8 +1132,8 @@ FilePath SavePackage::EnsureMimeExtension(const FilePath& name, return name; } -const FilePath::CharType *SavePackage::ExtensionForMimeType( - const FilePath::StringType& contents_mime_type) { +const FilePath::CharType* SavePackage::ExtensionForMimeType( + const std::string& contents_mime_type) { static const struct { const FilePath::CharType *mime_type; const FilePath::CharType *suggested_extension; @@ -1203,8 +1144,13 @@ const FilePath::CharType *SavePackage::ExtensionForMimeType( { FILE_PATH_LITERAL("text/plain"), FILE_PATH_LITERAL("txt") }, { FILE_PATH_LITERAL("text/css"), FILE_PATH_LITERAL("css") }, }; +#if defined(OS_POSIX) + FilePath::StringType mime_type(contents_mime_type); +#elif defined(OS_WIN) + FilePath::StringType mime_type(UTF8ToWide(contents_mime_type)); +#endif // OS_WIN for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(extensions); ++i) { - if (contents_mime_type == extensions[i].mime_type) + if (mime_type == extensions[i].mime_type) return extensions[i].suggested_extension; } return FILE_PATH_LITERAL(""); @@ -1235,41 +1181,52 @@ FilePath SavePackage::GetSaveDirPreference(PrefService* prefs) { } void SavePackage::GetSaveInfo() { + // Can't use tab_contents_ in the file thread, so get the data that we need + // before calling to it. PrefService* prefs = tab_contents_->profile()->GetPrefs(); FilePath website_save_dir = GetSaveDirPreference(prefs); FilePath download_save_dir = prefs->GetFilePath( prefs::kDownloadDefaultDirectory); + std::string mime_type = tab_contents_->contents_mime_type(); BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, - new CreateDownloadDirectoryTask(this, - website_save_dir, - download_save_dir)); - // CreateDownloadDirectoryTask calls ContinueGetSaveInfo() below. + NewRunnableMethod(this, &SavePackage::CreateDirectoryOnFileThread, + website_save_dir, download_save_dir, mime_type)); } -void SavePackage::ContinueGetSaveInfo(FilePath save_dir) { +void SavePackage::CreateDirectoryOnFileThread( + const FilePath& website_save_dir, + const FilePath& download_save_dir, + const std::string& mime_type) { + FilePath save_dir; + // If the default html/websites save folder doesn't exist... + if (!file_util::DirectoryExists(website_save_dir)) { + // If the default download dir doesn't exist, create it. + if (!file_util::DirectoryExists(download_save_dir)) + file_util::CreateDirectory(download_save_dir); + save_dir = download_save_dir; + } else { + // If it does exist, use the default save dir param. + save_dir = website_save_dir; + } + + bool can_save_as_complete = CanSaveAsComplete(mime_type); + FilePath suggested_path = save_dir.Append( + GetSuggestedNameForSaveAs(can_save_as_complete, mime_type)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, &SavePackage::ContinueGetSaveInfo, + suggested_path, can_save_as_complete)); +} + +void SavePackage::ContinueGetSaveInfo(const FilePath& suggested_path, + bool can_save_as_complete) { // Use "Web Page, Complete" option as default choice of saving page. int file_type_index = 2; SelectFileDialog::FileTypeInfo file_type_info; FilePath::StringType default_extension; - SavePackageParam* save_params = - new SavePackageParam(tab_contents_->contents_mime_type()); - - bool can_save_as_complete = - CanSaveAsComplete(save_params->current_tab_mime_type); - -#if defined(OS_POSIX) - FilePath::StringType mime_type(save_params->current_tab_mime_type); -#elif defined(OS_WIN) - FilePath::StringType mime_type( - UTF8ToWide(save_params->current_tab_mime_type)); -#endif // OS_WIN - - FilePath suggested_path = save_dir.Append( - GetSuggestedNameForSaveAs(can_save_as_complete, mime_type)); - // If the contents can not be saved as complete-HTML, do not show the // file filters. if (can_save_as_complete) { @@ -1316,34 +1273,32 @@ void SavePackage::ContinueGetSaveInfo(FilePath save_dir) { default_extension, platform_util::GetTopLevel( tab_contents_->GetNativeView()), - save_params); + NULL); } else { // Just use 'suggested_path' instead of opening the dialog prompt. - ContinueSave(save_params, suggested_path, file_type_index); - delete save_params; + ContinueSave(suggested_path, file_type_index); } } // Called after the save file dialog box returns. -void SavePackage::ContinueSave(SavePackageParam* param, - const FilePath& final_name, +void SavePackage::ContinueSave(const FilePath& final_name, int index) { // Ensure the filename is safe. - param->saved_main_file_path = final_name; - download_util::GenerateSafeFileName(param->current_tab_mime_type, - ¶m->saved_main_file_path); + saved_main_file_path_ = final_name; + download_util::GenerateSafeFileName(tab_contents_->contents_mime_type(), + &saved_main_file_path_); // The option index is not zero-based. DCHECK(index > 0 && index < 3); - param->dir = param->saved_main_file_path.DirName(); + saved_main_directory_path_ = saved_main_file_path_.DirName(); PrefService* prefs = tab_contents_->profile()->GetPrefs(); StringPrefMember save_file_path; save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL); #if defined(OS_POSIX) - std::string path_string = param->dir.value(); + std::string path_string = saved_main_directory_path_.value(); #elif defined(OS_WIN) - std::string path_string = WideToUTF8(param->dir.value()); + std::string path_string = WideToUTF8(saved_main_directory_path_.value()); #endif // If user change the default saving directory, we will remember it just // like IE and FireFox. @@ -1352,20 +1307,16 @@ void SavePackage::ContinueSave(SavePackageParam* param, save_file_path.SetValue(path_string); } - param->save_type = (index == 1) ? SavePackage::SAVE_AS_ONLY_HTML : - SavePackage::SAVE_AS_COMPLETE_HTML; + save_type_ = (index == 1) ? SavePackage::SAVE_AS_ONLY_HTML : + SavePackage::SAVE_AS_COMPLETE_HTML; - if (param->save_type == SavePackage::SAVE_AS_COMPLETE_HTML) { + if (save_type_ == SavePackage::SAVE_AS_COMPLETE_HTML) { // Make new directory for saving complete file. - param->dir = param->dir.Append( - param->saved_main_file_path.RemoveExtension().BaseName().value() + + saved_main_directory_path_ = saved_main_directory_path_.Append( + saved_main_file_path_.RemoveExtension().BaseName().value() + FILE_PATH_LITERAL("_files")); } - save_type_ = param->save_type; - saved_main_file_path_ = param->saved_main_file_path; - saved_main_directory_path_ = param->dir; - Init(); } @@ -1394,12 +1345,8 @@ bool SavePackage::IsSavableContents(const std::string& contents_mime_type) { // SelectFileDialog::Listener interface. void SavePackage::FileSelected(const FilePath& path, int index, void* params) { - SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); - ContinueSave(save_params, path, index); - delete save_params; + ContinueSave(path, index); } void SavePackage::FileSelectionCanceled(void* params) { - SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); - delete save_params; } diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h index 68b3bf6..e7080a8 100644 --- a/chrome/browser/download/save_package.h +++ b/chrome/browser/download/save_package.h @@ -127,10 +127,6 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, int id() const { return unique_id_; } void GetSaveInfo(); - void ContinueGetSaveInfo(FilePath save_dir); - void ContinueSave(SavePackageParam* param, - const FilePath& final_name, - int index); // RenderViewHostDelegate::Save ---------------------------------------------- @@ -202,6 +198,13 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, // Retrieves the URL to be saved from tab_contents_ variable. GURL GetUrlToBeSaved(); + void CreateDirectoryOnFileThread(const FilePath& website_save_dir, + const FilePath& download_save_dir, + const std::string& mime_type); + void ContinueGetSaveInfo(const FilePath& suggested_path, + bool can_save_as_complete); + void ContinueSave(const FilePath& final_name, int index); + typedef base::hash_map<std::string, SaveItem*> SaveUrlItemMap; // in_progress_items_ is map of all saving job in in-progress state. @@ -228,7 +231,7 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, // suggested name is determined by the web document's title. FilePath GetSuggestedNameForSaveAs( bool can_save_as_complete, - const FilePath::StringType& contents_mime_type); + const std::string& contents_mime_type); // Ensures that the file name has a proper extension for HTML by adding ".htm" // if necessary. @@ -237,12 +240,12 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, // Ensures that the file name has a proper extension for supported formats // if necessary. static FilePath EnsureMimeExtension(const FilePath& name, - const FilePath::StringType& contents_mime_type); + const std::string& contents_mime_type); // Returns extension for supported MIME types (for example, for "text/plain" // it returns "txt"). static const FilePath::CharType* ExtensionForMimeType( - const FilePath::StringType& contents_mime_type); + const std::string& contents_mime_type); typedef std::queue<SaveItem*> SaveItemQueue; // A queue for items we are about to start saving. diff --git a/chrome/browser/download/save_package_unittest.cc b/chrome/browser/download/save_package_unittest.cc index b315097..948280f 100644 --- a/chrome/browser/download/save_package_unittest.cc +++ b/chrome/browser/download/save_package_unittest.cc @@ -82,7 +82,7 @@ class SavePackageTest : public RenderViewHostTestHarness { } FilePath EnsureMimeExtension(const FilePath& name, - const FilePath::StringType& content_mime_type) { + const std::string& content_mime_type) { return SavePackage::EnsureMimeExtension(name, content_mime_type); } @@ -242,35 +242,35 @@ TEST_F(SavePackageTest, TestEnsureMimeExtension) { static const struct { const FilePath::CharType* page_title; const FilePath::CharType* expected_name; - const FilePath::CharType* contents_mime_type; + const char* contents_mime_type; } kExtensionTests[] = { - { FPL("filename.html"), FPL("filename.html"), FPL("text/html") }, - { FPL("filename.htm"), FPL("filename.htm"), FPL("text/html") }, - { FPL("filename.xhtml"), FPL("filename.xhtml"), FPL("text/html") }, + { FPL("filename.html"), FPL("filename.html"), "text/html" }, + { FPL("filename.htm"), FPL("filename.htm"), "text/html" }, + { FPL("filename.xhtml"), FPL("filename.xhtml"), "text/html" }, #if defined(OS_WIN) - { FPL("filename"), FPL("filename.htm"), FPL("text/html") }, + { FPL("filename"), FPL("filename.htm"), "text/html" }, #else // defined(OS_WIN) - { FPL("filename"), FPL("filename.html"), FPL("text/html") }, + { FPL("filename"), FPL("filename.html"), "text/html" }, #endif // defined(OS_WIN) - { FPL("filename.html"), FPL("filename.html"), FPL("text/xml") }, - { FPL("filename.xml"), FPL("filename.xml"), FPL("text/xml") }, - { FPL("filename"), FPL("filename.xml"), FPL("text/xml") }, + { FPL("filename.html"), FPL("filename.html"), "text/xml" }, + { FPL("filename.xml"), FPL("filename.xml"), "text/xml" }, + { FPL("filename"), FPL("filename.xml"), "text/xml" }, { FPL("filename.xhtml"), FPL("filename.xhtml"), - FPL("application/xhtml+xml") }, + "application/xhtml+xml" }, { FPL("filename.html"), FPL("filename.html"), - FPL("application/xhtml+xml") }, - { FPL("filename"), FPL("filename.xhtml"), FPL("application/xhtml+xml") }, - { FPL("filename.txt"), FPL("filename.txt"), FPL("text/plain") }, - { FPL("filename"), FPL("filename.txt"), FPL("text/plain") }, - { FPL("filename.css"), FPL("filename.css"), FPL("text/css") }, - { FPL("filename"), FPL("filename.css"), FPL("text/css") }, - { FPL("filename.abc"), FPL("filename.abc"), FPL("unknown/unknown") }, - { FPL("filename"), FPL("filename"), FPL("unknown/unknown") }, + "application/xhtml+xml" }, + { FPL("filename"), FPL("filename.xhtml"), "application/xhtml+xml" }, + { FPL("filename.txt"), FPL("filename.txt"), "text/plain" }, + { FPL("filename"), FPL("filename.txt"), "text/plain" }, + { FPL("filename.css"), FPL("filename.css"), "text/css" }, + { FPL("filename"), FPL("filename.css"), "text/css" }, + { FPL("filename.abc"), FPL("filename.abc"), "unknown/unknown" }, + { FPL("filename"), FPL("filename"), "unknown/unknown" }, }; for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(kExtensionTests); ++i) { FilePath original = FilePath(kExtensionTests[i].page_title); FilePath expected = FilePath(kExtensionTests[i].expected_name); - FilePath::StringType mime_type(kExtensionTests[i].contents_mime_type); + std::string mime_type(kExtensionTests[i].contents_mime_type); FilePath actual = EnsureMimeExtension(original, mime_type); EXPECT_EQ(expected.value(), actual.value()) << "Failed for page title: " << kExtensionTests[i].page_title << " MIME:" << mime_type; @@ -338,7 +338,7 @@ TEST_F(SavePackageTest, TestSuggestedSaveNames) { FilePath save_name = save_package->GetSuggestedNameForSaveAs( kSuggestedSaveNames[i].ensure_html_extension, - FilePath::StringType()); + std::string()); EXPECT_EQ(kSuggestedSaveNames[i].expected_name, save_name.value()) << "Test case " << i; } diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc index bed7228..fe777e4 100644 --- a/chrome/browser/download/save_page_browsertest.cc +++ b/chrome/browser/download/save_page_browsertest.cc @@ -6,7 +6,7 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/scoped_temp_dir.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/net/url_request_mock_http_job.h" diff --git a/chrome/browser/download/save_page_uitest.cc b/chrome/browser/download/save_page_uitest.cc index 07fd78c..e6c6e08 100644 --- a/chrome/browser/download/save_page_uitest.cc +++ b/chrome/browser/download/save_page_uitest.cc @@ -7,7 +7,7 @@ #include "base/platform_thread.h" #include "base/string_util.h" #include "base/test/test_file_util.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/net/url_request_mock_http_job.h" #include "chrome/browser/download/save_package.h" #include "chrome/common/chrome_paths.h" |
