diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-06 23:31:41 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-06 23:31:41 +0000 |
commit | 7ae7c2cbd38f886f4056fa7434a6c1189d98ffd2 (patch) | |
tree | e606471e20eb79fea7a05c9005869065bf865ca1 | |
parent | cab465ccf2a93d84e0f16987d8754ac2673eb118 (diff) | |
download | chromium_src-7ae7c2cbd38f886f4056fa7434a6c1189d98ffd2.zip chromium_src-7ae7c2cbd38f886f4056fa7434a6c1189d98ffd2.tar.gz chromium_src-7ae7c2cbd38f886f4056fa7434a6c1189d98ffd2.tar.bz2 |
Convert download manager to FilePath.
(Fixed up version of issue 17032. Now passes all unit tests.)
Review URL: http://codereview.chromium.org/16533
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7630 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 270 insertions, 240 deletions
diff --git a/base/file_path.h b/base/file_path.h index 7beb40e..6ed9320 100644 --- a/base/file_path.h +++ b/base/file_path.h @@ -129,6 +129,8 @@ class FilePath { const StringType& value() const { return path_; } + bool empty() const { return path_.empty(); } + // Returns true if |character| is in kSeparators. static bool IsSeparator(CharType character); diff --git a/base/file_util.cc b/base/file_util.cc index fe33c32..fe7b694 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -79,12 +79,13 @@ void TrimTrailingSeparator(std::wstring* dir) { dir->resize(dir->length() - 1); } -std::wstring GetFileExtensionFromPath(const std::wstring& path) { - std::wstring file_name = GetFilenameFromPath(path); - std::wstring::size_type last_dot = file_name.rfind(L'.'); - return std::wstring(last_dot == std::wstring::npos ? - L"" : - file_name, last_dot+1); +FilePath::StringType GetFileExtensionFromPath(const FilePath& path) { + FilePath::StringType file_name = path.BaseName().value(); + const FilePath::StringType::size_type last_dot = + file_name.rfind(kExtensionSeparator); + return FilePath::StringType(last_dot == FilePath::StringType::npos ? + FILE_PATH_LITERAL("") : + file_name, last_dot+1); } std::wstring GetFilenameWithoutExtensionFromPath(const std::wstring& path) { @@ -374,6 +375,15 @@ bool GetCurrentDirectory(std::wstring* path_str) { *path_str = path.ToWStringHack(); return true; } +std::wstring GetFileExtensionFromPath(const std::wstring& path) { + FilePath::StringType extension = + GetFileExtensionFromPath(FilePath::FromWStringHack(path)); +#if defined(OS_WIN) + return extension; +#elif defined(OS_POSIX) + return UTF8ToWide(extension); +#endif +} bool GetFileInfo(const std::wstring& file_path, FileInfo* results) { return GetFileInfo(FilePath::FromWStringHack(file_path), results); } diff --git a/base/file_util.h b/base/file_util.h index 67cd59f..784ea36 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -77,6 +77,8 @@ std::wstring GetFilenameFromPath(const std::wstring& path); // Returns "jpg" for path "C:\pics\jojo.jpg", or an empty string if // the file has no extension. +FilePath::StringType GetFileExtensionFromPath(const FilePath& path); +// Deprecated temporary compatibility function. std::wstring GetFileExtensionFromPath(const std::wstring& path); // Returns 'jojo' for path "C:\pics\jojo.jpg". @@ -464,8 +466,8 @@ class MemoryMappedFile { // Renames a file using the SHFileOperation API to ensure that the target file // gets the correct default security descriptor in the new path. bool RenameFileAndResetSecurityDescriptor( - const std::wstring& source_file_path, - const std::wstring& target_file_path); + const FilePath& source_file_path, + const FilePath& target_file_path); } // namespace file_util diff --git a/base/file_util_win.cc b/base/file_util_win.cc index c2dbf0a..b50ab09 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -549,12 +549,11 @@ int WriteFile(const std::wstring& filename, const char* data, int size) { return -1; } -bool RenameFileAndResetSecurityDescriptor( - const std::wstring& source_file_path, - const std::wstring& target_file_path) { +bool RenameFileAndResetSecurityDescriptor(const FilePath& source_file_path, + const FilePath& target_file_path) { // The parameters to SHFileOperation must be terminated with 2 NULL chars. - std::wstring source = source_file_path; - std::wstring target = target_file_path; + std::wstring source = source_file_path.value(); + std::wstring target = target_file_path.value(); source.append(1, L'\0'); target.append(1, L'\0'); diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index ec31959..4b3c2e4 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -1903,7 +1903,7 @@ void AutomationProvider::GetDownloadDirectory(const IPC::Message& message, NavigationController* tab = tab_tracker_->GetResource(handle); DownloadManager* dlm = tab->profile()->GetDownloadManager(); DCHECK(dlm); - download_directory = dlm->download_path(); + download_directory = dlm->download_path().ToWStringHack(); } Send(new AutomationMsg_DownloadDirectoryResponse(message.routing_id(), diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc index b06be04..da4c3b1 100644 --- a/chrome/browser/download/download_file.cc +++ b/chrome/browser/download/download_file.cc @@ -85,22 +85,21 @@ bool DownloadFile::AppendDataToFile(const char* data, int data_len) { void DownloadFile::Cancel() { Close(); - DeleteFile(full_path_.c_str()); + file_util::Delete(full_path_, false); } // The UI has provided us with our finalized name. -bool DownloadFile::Rename(const std::wstring& new_path) { +bool DownloadFile::Rename(const FilePath& new_path) { Close(); // We cannot rename because rename will keep the same security descriptor // on the destination file. We want to recreate the security descriptor // with the security that makes sense in the new path. - if (!file_util::RenameFileAndResetSecurityDescriptor(full_path_.c_str(), - new_path.c_str())) { + if (!file_util::RenameFileAndResetSecurityDescriptor(full_path_, new_path)) { return false; } - DeleteFile(full_path_.c_str()); + file_util::Delete(full_path_, false); full_path_ = new_path; path_renamed_ = true; @@ -512,15 +511,15 @@ void DownloadFileManager::OnDownloadUrl(const GURL& url, // Open a download, or show it in a Windows Explorer window. We run on this // thread to avoid blocking the UI with (potentially) slow Shell operations. // TODO(paulg): File 'stat' operations. -void DownloadFileManager::OnShowDownloadInShell(const std::wstring full_path) { +void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) { DCHECK(MessageLoop::current() == file_loop_); - win_util::ShowItemInFolder(full_path); + win_util::ShowItemInFolder(full_path.value()); } // Launches the selected download using ShellExecute 'open' verb. If there is // a valid parent window, the 'safer' version will be used which can // display a modal dialog asking for user consent on dangerous files. -void DownloadFileManager::OnOpenDownloadInShell(const std::wstring full_path, +void DownloadFileManager::OnOpenDownloadInShell(const FilePath& full_path, const std::wstring& url, HWND parent_window) { DCHECK(MessageLoop::current() == file_loop_); @@ -535,15 +534,13 @@ void DownloadFileManager::OnOpenDownloadInShell(const std::wstring full_path, // download specified by 'id'. Rename the in progress download, and remove it // from our table if it has been completed or cancelled already. void DownloadFileManager::OnFinalDownloadName(int id, - const std::wstring& full_path) { + const FilePath& full_path) { DCHECK(MessageLoop::current() == file_loop_); DownloadFileMap::iterator it = downloads_.find(id); if (it == downloads_.end()) return; - std::wstring download_dir = file_util::GetDirectoryFromPath(full_path); - if (!file_util::PathExists(download_dir)) - file_util::CreateDirectory(download_dir); + file_util::CreateDirectory(full_path.DirName()); DownloadFile* download = it->second; if (!download->Rename(full_path)) { @@ -576,13 +573,9 @@ void DownloadFileManager::OnFinalDownloadName(int id, this, &DownloadFileManager::StopUpdateTimer)); } -void DownloadFileManager::CreateDirectory(const std::wstring& directory) { - if (!file_util::PathExists(directory)) - file_util::CreateDirectory(directory); -} - -void DownloadFileManager::DeleteFile(const std::wstring& path) { +// static +void DownloadFileManager::DeleteFile(const FilePath& path) { // Make sure we only delete files. - if (file_util::PathExists(path) && !file_util::DirectoryExists(path)) + if (!file_util::DirectoryExists(path)) file_util::Delete(path, false); } diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h index cce6398..ea74318 100644 --- a/chrome/browser/download/download_file.h +++ b/chrome/browser/download/download_file.h @@ -53,6 +53,7 @@ #include "chrome/browser/history/download_types.h" class DownloadManager; +class FilePath; class GURL; class MessageLoop; class ResourceDispatcherHost; @@ -93,12 +94,12 @@ class DownloadFile { void Cancel(); // Rename the download file. Returns 'true' if the rename was successful. - bool Rename(const std::wstring& full_path); + bool Rename(const FilePath& full_path); // Accessors. int64 bytes_so_far() const { return bytes_so_far_; } int id() const { return id_; } - std::wstring full_path() const { return full_path_; } + FilePath full_path() const { return full_path_; } int render_process_id() const { return render_process_id_; } int render_view_id() const { return render_view_id_; } int request_id() const { return request_id_; } @@ -132,7 +133,7 @@ class DownloadFile { int64 bytes_so_far_; // Full path to the downloaded file. - std::wstring full_path_; + FilePath full_path_; // Whether the download is still using its initial temporary path. bool path_renamed_; @@ -192,26 +193,22 @@ class DownloadFileManager void RemoveDownload(int id, DownloadManager* manager); // Handler for shell operations sent from the UI to the download thread. - void OnShowDownloadInShell(const std::wstring full_path); + void OnShowDownloadInShell(const FilePath& full_path); // Handler to open or execute a downloaded file. - void OnOpenDownloadInShell(const std::wstring full_path, + void OnOpenDownloadInShell(const FilePath& full_path, const std::wstring& url, HWND parent_window); // The download manager has provided a final name for a download. Sent from // the UI thread and run on the download thread. - void OnFinalDownloadName(int id, const std::wstring& full_path); + void OnFinalDownloadName(int id, const FilePath& full_path); // Timer notifications. void UpdateInProgressDownloads(); MessageLoop* file_loop() const { return file_loop_; } - // Called by the download manager at initialization to ensure the default - // download directory exists. - void CreateDirectory(const std::wstring& directory); - - // Called by the donwload manager to delete non validated dangerous downloads. - void DeleteFile(const std::wstring& path); + // Called by the download manager to delete non validated dangerous downloads. + static void DeleteFile(const FilePath& path); private: // Timer helpers for updating the UI about the current progress of a download. diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index bb80bf0..199b8df 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -65,22 +65,23 @@ static const int kUninitializedHandle = 0; // Appends the passed the number between parenthesis the path before the // extension. -static void AppendNumberToPath(std::wstring* path, int number) { - file_util::InsertBeforeExtension(path, StringPrintf(L" (%d)", number)); +static void AppendNumberToPath(FilePath* path, int number) { + file_util::InsertBeforeExtension(path, + StringPrintf(FILE_PATH_LITERAL(" (%d)"), number)); } // Attempts to find a number that can be appended to that path to make it // unique. If |path| does not exist, 0 is returned. If it fails to find such // a number, -1 is returned. -static int GetUniquePathNumber(const std::wstring& path) { +static int GetUniquePathNumber(const FilePath& path) { const int kMaxAttempts = 100; if (!file_util::PathExists(path)) return 0; - std::wstring new_path; + FilePath new_path; for (int count = 1; count <= kMaxAttempts; ++count) { - new_path.assign(path); + new_path = FilePath(path); AppendNumberToPath(&new_path, count); if (!file_util::PathExists(new_path)) @@ -90,8 +91,8 @@ static int GetUniquePathNumber(const std::wstring& path) { return -1; } -static bool DownloadPathIsDangerous(const std::wstring& download_path) { - std::wstring desktop_dir; +static bool DownloadPathIsDangerous(const FilePath& download_path) { + FilePath desktop_dir; if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_dir)) { NOTREACHED(); return false; @@ -126,10 +127,10 @@ DownloadItem::DownloadItem(const DownloadCreateInfo& info) // Constructor for DownloadItem created via user action in the main thread. DownloadItem::DownloadItem(int32 download_id, - const std::wstring& path, + const FilePath& path, int path_uniquifier, const std::wstring& url, - const std::wstring& original_name, + const FilePath& original_name, const Time start_time, int64 download_size, int render_process_id, @@ -156,7 +157,7 @@ DownloadItem::DownloadItem(int32 download_id, } void DownloadItem::Init(bool start_timer) { - file_name_ = file_util::GetFilenameFromPath(full_path_); + file_name_ = full_path_.BaseName(); if (start_timer) StartProgressTimer(); } @@ -261,10 +262,10 @@ int DownloadItem::PercentComplete() const { return percent; } -void DownloadItem::Rename(const std::wstring& full_path) { +void DownloadItem::Rename(const FilePath& full_path) { DCHECK(!full_path.empty()); full_path_ = full_path; - file_name_ = file_util::GetFilenameFromPath(full_path_); + file_name_ = full_path_.BaseName(); } void DownloadItem::TogglePause() { @@ -274,11 +275,11 @@ void DownloadItem::TogglePause() { UpdateObservers(); } -std::wstring DownloadItem::GetFileName() const { +FilePath DownloadItem::GetFileName() const { if (safety_state_ == DownloadItem::SAFE) return file_name_; if (path_uniquifier_ > 0) { - std::wstring name(original_name_); + FilePath name(original_name_); AppendNumberToPath(&name, path_uniquifier_); return name; } @@ -294,24 +295,24 @@ void DownloadManager::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); // The default download path is userprofile\download. - std::wstring default_download_path; + FilePath default_download_path; if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &default_download_path)) { NOTREACHED(); } prefs->RegisterStringPref(prefs::kDownloadDefaultDirectory, - default_download_path); + default_download_path.ToWStringHack()); // If the download path is dangerous we forcefully reset it. But if we do // so we set a flag to make sure we only do it once, to avoid fighting // the user if he really wants it on an unsafe place such as the desktop. if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) { - std::wstring current_download_dir = - prefs->GetString(prefs::kDownloadDefaultDirectory); + FilePath current_download_dir = FilePath::FromWStringHack( + prefs->GetString(prefs::kDownloadDefaultDirectory)); if (DownloadPathIsDangerous(current_download_dir)) { prefs->SetString(prefs::kDownloadDefaultDirectory, - default_download_path); + default_download_path.ToWStringHack()); } prefs->SetBoolean(prefs::kDownloadDirUpgraded, true); } @@ -479,9 +480,14 @@ bool DownloadManager::Init(Profile* profile) { download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); + // This variable is needed to resolve which CreateDirectory we want to point + // to. Without it, the NewRunnableFunction cannot resolve the ambiguity. + // TODO(estade): when file_util::CreateDirectory(wstring) is removed, + // get rid of |CreateDirectoryPtr|. + bool (*CreateDirectoryPtr)(const FilePath&) = &file_util::CreateDirectory; // Ensure that the download directory specified in the preferences exists. - file_loop_->PostTask(FROM_HERE, NewRunnableMethod( - file_manager_, &DownloadFileManager::CreateDirectory, *download_path_)); + file_loop_->PostTask(FROM_HERE, NewRunnableFunction( + CreateDirectoryPtr, download_path())); // We store any file extension that should be opened automatically at // download completion in this pref. @@ -527,19 +533,17 @@ void DownloadManager::StartDownload(DownloadCreateInfo* info) { // Determine the proper path for a download, by choosing either the default // download directory, or prompting the user. - std::wstring generated_name; + FilePath generated_name; GenerateFilename(info, &generated_name); if (info->save_as && !last_download_path_.empty()) info->suggested_path = last_download_path_; else - info->suggested_path = *download_path_; - file_util::AppendToPath(&info->suggested_path, generated_name); + info->suggested_path = download_path(); + info->suggested_path = info->suggested_path.Append(generated_name); if (!info->save_as) { // Let's check if this download is dangerous, based on its name. - const std::wstring filename = - file_util::GetFilenameFromPath(info->suggested_path); - info->is_dangerous = IsDangerous(filename); + info->is_dangerous = IsDangerous(info->suggested_path.BaseName()); } // We need to move over to the download thread because we don't want to stat @@ -555,31 +559,29 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { // Check writability of the suggested path. If we can't write to it, default // to the user's "My Documents" directory. We'll prompt them in this case. - std::wstring dir = file_util::GetDirectoryFromPath(info->suggested_path); - const std::wstring filename = - file_util::GetFilenameFromPath(info->suggested_path); + FilePath dir = info->suggested_path.DirName(); + FilePath filename = info->suggested_path.BaseName(); if (!file_util::PathIsWritable(dir)) { info->save_as = true; PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); - file_util::AppendToPath(&info->suggested_path, filename); + info->suggested_path = info->suggested_path.Append(filename); } info->path_uniquifier = GetUniquePathNumber(info->suggested_path); // If the download is deemed dangerous, we'll use a temporary name for it. if (info->is_dangerous) { - info->original_name = file_util::GetFilenameFromPath(info->suggested_path); + info->original_name = FilePath(info->suggested_path).BaseName(); // Create a temporary file to hold the file until the user approves its // download. - std::wstring file_name; - std::wstring path; + FilePath::StringType file_name; + FilePath path; while (path.empty()) { - SStringPrintf(&file_name, L"unconfirmed %d.download", + SStringPrintf(&file_name, FILE_PATH_LITERAL("unconfirmed %d.download"), base::RandInt(0, 100000)); - path = dir; - file_util::AppendToPath(&path, file_name); + path = dir.Append(file_name); if (file_util::PathExists(path)) - path.clear(); + path = FilePath(); } info->suggested_path = path; } else { @@ -599,7 +601,7 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { // Create an empty file at the suggested path so that we don't allocate the // same "non-existant" path to multiple downloads. // See: http://code.google.com/p/chromium/issues/detail?id=3662 - file_util::WriteFile(info->suggested_path, "", 0); + file_util::WriteFile(info->suggested_path.ToWStringHack(), "", 0); } // Now we return to the UI thread. @@ -620,11 +622,13 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { WebContents* contents = tab_util::GetWebContentsByID( info->render_process_id, info->render_view_id); - std::wstring filter = win_util::GetFileFilterFromPath(info->suggested_path); + std::wstring filter = + win_util::GetFileFilterFromPath(info->suggested_path.value()); HWND owning_hwnd = contents ? GetAncestor(contents->GetContainerHWND(), GA_ROOT) : NULL; select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, - std::wstring(), info->suggested_path, + std::wstring(), + info->suggested_path.ToWStringHack(), filter, std::wstring(), owning_hwnd, info); } else { @@ -634,7 +638,7 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { } void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info, - const std::wstring& target_path) { + const FilePath& target_path) { scoped_ptr<DownloadCreateInfo> infop(info); info->path = target_path; @@ -809,14 +813,13 @@ void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { // Called on the file thread. Renames the downloaded file to its original name. void DownloadManager::ProceedWithFinishedDangerousDownload( int64 download_handle, - const std::wstring& path, - const std::wstring& original_name) { + const FilePath& path, + const FilePath& original_name) { bool success = false; - std::wstring new_path = path; + FilePath new_path; int uniquifier = 0; if (file_util::PathExists(path)) { - new_path = file_util::GetDirectoryFromPath(new_path); - file_util::AppendToPath(&new_path, original_name); + new_path = new_path.DirName().Append(original_name); // Make our name unique at this point, as if a dangerous file is downloading // and a 2nd download is started for a file with the same name, they would // have the same path. This is because we uniquify the name on download @@ -838,7 +841,7 @@ void DownloadManager::ProceedWithFinishedDangerousDownload( // Call from the file thread when the finished dangerous download was renamed. void DownloadManager::DangerousDownloadRenamed(int64 download_handle, bool success, - const std::wstring& new_path, + const FilePath& new_path, int new_path_uniquifier) { DownloadMap::iterator it = downloads_.find(download_handle); if (it == downloads_.end()) { @@ -937,13 +940,13 @@ void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh, rdh->PauseRequest(render_process_id, request_id, pause); } -bool DownloadManager::IsDangerous(const std::wstring& file_name) { +bool DownloadManager::IsDangerous(const FilePath& file_name) { // TODO(jcampan): Improve me. return IsExecutable(file_util::GetFileExtensionFromPath(file_name)); } void DownloadManager::RenameDownload(DownloadItem* download, - const std::wstring& new_path) { + const FilePath& new_path) { download->Rename(new_path); // Update the history. @@ -955,7 +958,7 @@ void DownloadManager::RenameDownload(DownloadItem* download, // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong. HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); if (hs) - hs->UpdateDownloadPath(new_path, download->db_handle()); + hs->UpdateDownloadPath(new_path.ToWStringHack(), download->db_handle()); } void DownloadManager::RemoveDownload(int64 download_handle) { @@ -1046,9 +1049,10 @@ void DownloadManager::NotifyAboutDownloadStop() { NotificationService::NoDetails()); } -void DownloadManager::GenerateExtension(const std::wstring& file_name, - const std::string& mime_type, - std::wstring* generated_extension) { +void DownloadManager::GenerateExtension( + const FilePath& file_name, + const std::string& mime_type, + FilePath::StringType* generated_extension) { // We're worried about three things here: // // 1) Security. Many sites let users upload content, such as buddy icons, to @@ -1064,17 +1068,20 @@ void DownloadManager::GenerateExtension(const std::wstring& file_name, // the shell. We block these extensions to prevent a malicious web site // from integrating with the user's shell. - static const wchar_t default_extension[] = L"download"; + static const FilePath::CharType default_extension[] = + FILE_PATH_LITERAL("download"); // See if our file name already contains an extension. - std::wstring extension(file_util::GetFileExtensionFromPath(file_name)); + FilePath::StringType extension( + file_util::GetFileExtensionFromPath(file_name)); // Rename shell-integrated extensions. if (win_util::IsShellIntegratedExtension(extension)) extension.assign(default_extension); std::string mime_type_from_extension; - net::GetMimeTypeFromFile(file_name, &mime_type_from_extension); + net::GetMimeTypeFromFile(file_name.ToWStringHack(), + &mime_type_from_extension); if (mime_type == mime_type_from_extension) { // The hinted extension matches the mime type. It looks like a winner. generated_extension->swap(extension); @@ -1099,12 +1106,13 @@ void DownloadManager::GenerateExtension(const std::wstring& file_name, // 1. New extension is not ".txt" // 2. New extension is not the same as the already existing extension. // 3. New extension is not executable. This action mitigates the case when - // an execuatable is hidden in a benign file extension; + // an executable is hidden in a benign file extension; // E.g. my-cat.jpg becomes my-cat.jpg.js if content type is // application/x-javascript. - std::wstring append_extension; + FilePath::StringType append_extension; if (net::GetPreferredExtensionForMimeType(mime_type, &append_extension)) { - if (append_extension != L".txt" && append_extension != extension && + if (append_extension != FILE_PATH_LITERAL(".txt") && + append_extension != extension && !IsExecutable(append_extension)) extension += append_extension; } @@ -1114,15 +1122,14 @@ void DownloadManager::GenerateExtension(const std::wstring& file_name, } void DownloadManager::GenerateFilename(DownloadCreateInfo* info, - std::wstring* generated_name) { - std::wstring file_name = + FilePath* generated_name) { + *generated_name = FilePath::FromWStringHack( net::GetSuggestedFilename(GURL(info->url), info->content_disposition, - L"download"); - DCHECK(!file_name.empty()); + L"download")); + DCHECK(!generated_name->empty()); - GenerateSafeFilename(info->mime_type, &file_name); - generated_name->assign(file_name); + GenerateSafeFilename(info->mime_type, generated_name); } void DownloadManager::AddObserver(Observer* observer) { @@ -1141,7 +1148,7 @@ void DownloadManager::ShowDownloadInShell(const DownloadItem* download) { file_loop_->PostTask(FROM_HERE, NewRunnableMethod(file_manager_, &DownloadFileManager::OnShowDownloadInShell, - download->full_path())); + FilePath(download->full_path()))); } void DownloadManager::OpenDownloadInShell(const DownloadItem* download, @@ -1153,8 +1160,8 @@ void DownloadManager::OpenDownloadInShell(const DownloadItem* download, download->full_path(), download->url(), parent_window)); } -void DownloadManager::OpenFilesOfExtension(const std::wstring& extension, - bool open) { +void DownloadManager::OpenFilesOfExtension( + const FilePath::StringType& extension, bool open) { if (open && !IsExecutable(extension)) auto_open_.insert(extension); else @@ -1162,7 +1169,8 @@ void DownloadManager::OpenFilesOfExtension(const std::wstring& extension, SaveAutoOpens(); } -bool DownloadManager::ShouldOpenFileExtension(const std::wstring& extension) { +bool DownloadManager::ShouldOpenFileExtension( + const FilePath::StringType& extension) { if (!IsExecutable(extension) && auto_open_.find(extension) != auto_open_.end()) return true; @@ -1198,7 +1206,7 @@ bool DownloadManager::IsExecutableMimeType(const std::string& mime_type) { return net::MatchesMimeType("application/*", mime_type); } -bool DownloadManager::IsExecutable(const std::wstring& extension) { +bool DownloadManager::IsExecutable(const FilePath::StringType& extension) { return exe_types_.find(extension) != exe_types_.end(); } @@ -1214,10 +1222,10 @@ bool DownloadManager::HasAutoOpenFileTypesRegistered() const { void DownloadManager::SaveAutoOpens() { PrefService* prefs = profile_->GetPrefs(); if (prefs) { - std::wstring extensions; - for (std::set<std::wstring>::iterator it = auto_open_.begin(); + FilePath::StringType extensions; + for (std::set<FilePath::StringType>::iterator it = auto_open_.begin(); it != auto_open_.end(); ++it) { - extensions += *it + L":"; + extensions += *it + FILE_PATH_LITERAL(":"); } if (!extensions.empty()) extensions.erase(extensions.size() - 1); @@ -1225,10 +1233,12 @@ void DownloadManager::SaveAutoOpens() { } } -void DownloadManager::FileSelected(const std::wstring& path, void* params) { +void DownloadManager::FileSelected(const std::wstring& path_string, + void* params) { + FilePath path = FilePath::FromWStringHack(path_string); DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); if (info->save_as) - last_download_path_ = file_util::GetDirectoryFromPath(path); + last_download_path_ = path.DirName(); ContinueStartDownload(info, path); } @@ -1241,9 +1251,9 @@ void DownloadManager::FileSelectionCanceled(void* params) { info->download_id)); } -void DownloadManager::DeleteDownload(const std::wstring& path) { - file_loop_->PostTask(FROM_HERE, NewRunnableMethod( - file_manager_, &DownloadFileManager::DeleteFile, path)); +void DownloadManager::DeleteDownload(const FilePath& path) { + file_loop_->PostTask(FROM_HERE, NewRunnableFunction( + &DownloadFileManager::DeleteFile, FilePath(path))); } @@ -1265,21 +1275,22 @@ void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { } void DownloadManager::GenerateSafeFilename(const std::string& mime_type, - std::wstring* file_name) { - // Make sure we get the right file extension. - std::wstring extension; + FilePath* file_name) { + // Make sure we get the right file extension + FilePath::StringType extension; GenerateExtension(*file_name, mime_type, &extension); file_util::ReplaceExtension(file_name, extension); // Prepend "_" to the file name if it's a reserved name - std::wstring leaf_name = file_util::GetFilenameFromPath(*file_name); + FilePath::StringType leaf_name = file_name->BaseName().value(); DCHECK(!leaf_name.empty()); if (win_util::IsReservedName(leaf_name)) { - file_util::UpOneDirectoryOrEmpty(file_name); - if (file_name->empty()) { - file_name->assign(std::wstring(L"_") + leaf_name); + leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name; + *file_name = file_name->DirName(); + if (file_name->value() == FilePath::kCurrentDirectory) { + *file_name = FilePath(leaf_name); } else { - file_util::AppendToPath(file_name, std::wstring(L"_") + leaf_name); + *file_name = file_name->Append(leaf_name); } } } @@ -1374,5 +1385,5 @@ void DownloadManager::OnSearchComplete(HistoryService::Handle handle, // Clears the last download path, used to initialize "save as" dialogs. void DownloadManager::ClearLastDownloadPath() { - last_download_path_.clear(); + last_download_path_ = FilePath(); } diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h index 959fe82..3d7bcc2 100644 --- a/chrome/browser/download/download_manager.h +++ b/chrome/browser/download/download_manager.h @@ -43,6 +43,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/file_path.h" #include "base/hash_tables.h" #include "base/observer_list.h" #include "base/ref_counted.h" @@ -102,10 +103,10 @@ class DownloadItem { // Constructing from user action: DownloadItem(int32 download_id, - const std::wstring& path, + const FilePath& path, int path_uniquifier, const std::wstring& url, - const std::wstring& original_name, + const FilePath& original_name, const base::Time start_time, int64 download_size, int render_process_id, @@ -164,17 +165,17 @@ class DownloadItem { // Update the download's path, the actual file is renamed on the download // thread. - void Rename(const std::wstring& full_path); + void Rename(const FilePath& full_path); // Allow the user to temporarily pause a download or resume a paused download. void TogglePause(); // Accessors DownloadState state() const { return state_; } - std::wstring file_name() const { return file_name_; } - void set_file_name(const std::wstring& name) { file_name_ = name; } - std::wstring full_path() const { return full_path_; } - void set_full_path(const std::wstring& path) { full_path_ = path; } + FilePath file_name() const { return file_name_; } + void set_file_name(const FilePath& name) { file_name_ = name; } + FilePath full_path() const { return full_path_; } + void set_full_path(const FilePath& path) { full_path_ = path; } int path_uniquifier() const { return path_uniquifier_; } void set_path_uniquifier(int uniquifier) { path_uniquifier_ = uniquifier; } std::wstring url() const { return url_; } @@ -197,13 +198,13 @@ class DownloadItem { void set_safety_state(SafetyState safety_state) { safety_state_ = safety_state; } - std::wstring original_name() const { return original_name_; } - void set_original_name(const std::wstring& name) { original_name_ = name; } + FilePath original_name() const { return original_name_; } + void set_original_name(const FilePath& name) { original_name_ = name; } // 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. - std::wstring GetFileName() const; + FilePath GetFileName() const; private: // Internal helper for maintaining consistent received and total sizes. @@ -213,14 +214,14 @@ class DownloadItem { int32 id_; // Full path to the downloaded file - std::wstring full_path_; + 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 - std::wstring file_name_; + FilePath file_name_; // The URL from whence we came, for display std::wstring url_; @@ -264,7 +265,7 @@ class DownloadItem { // Dangerous download are given temporary names until the user approves them. // This stores their original name. - std::wstring original_name_; + FilePath original_name_; // For canceling or pausing requests. int render_process_id_; @@ -371,7 +372,9 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, return static_cast<int>(in_progress_.size()); } - std::wstring download_path() { return *download_path_; } + FilePath download_path() { + return FilePath::FromWStringHack(*download_path_); + } // Clears the last download path, used to initialize "save as" dialogs. void ClearLastDownloadPath(); @@ -379,16 +382,16 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // Registers this file extension for automatic opening upon download // completion if 'open' is true, or prevents the extension from automatic // opening if 'open' is false. - void OpenFilesOfExtension(const std::wstring& extension, bool open); + void OpenFilesOfExtension(const FilePath::StringType& extension, bool open); // Tests if a file type should be opened automatically. - bool ShouldOpenFileExtension(const std::wstring& extension); + bool ShouldOpenFileExtension(const FilePath::StringType& extension); // Tests if we think the server means for this mime_type to be executable. static bool IsExecutableMimeType(const std::string& mime_type); // Tests if a file type is considered executable. - bool IsExecutable(const std::wstring& extension); + bool IsExecutable(const FilePath::StringType& extension); // Resets the automatic open preference. void ResetAutoOpenFiles(); @@ -398,11 +401,12 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, bool HasAutoOpenFileTypesRegistered() const; // Overridden from SelectFileDialog::Listener: + // TODO(port): convert this to FilePath when SelectFileDialog gets converted. virtual void FileSelected(const std::wstring& path, void* params); virtual void FileSelectionCanceled(void* params); // Deletes the specified path on the file thread. - void DeleteDownload(const std::wstring& path); + void DeleteDownload(const FilePath& path); // Called when the user has validated the donwload of a dangerous file. void DangerousDownloadValidated(DownloadItem* download); @@ -411,7 +415,7 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // download. |file_name| can either be just the file name or it can be a // full path to a file. void GenerateSafeFilename(const std::string& mime_type, - std::wstring* file_name); + FilePath* file_name); private: // Shutdown the download manager. This call is needed only after Init. @@ -430,7 +434,7 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // determined, either automatically based on the suggested file name, or by // the user in a Save As dialog box. void ContinueStartDownload(DownloadCreateInfo* info, - const std::wstring& target_path); + const FilePath& target_path); // Update the history service for a particular download. void UpdateHistoryForDownload(DownloadItem* download); @@ -443,12 +447,12 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, void NotifyAboutDownloadStop(); // Create an extension based on the file name and mime type. - void GenerateExtension(const std::wstring& file_name, + void GenerateExtension(const FilePath& file_name, const std::string& mime_type, - std::wstring* generated_extension); + FilePath::StringType* generated_extension); // Create a file name based on the response from the server. - void GenerateFilename(DownloadCreateInfo* info, std::wstring* generated_name); + void GenerateFilename(DownloadCreateInfo* info, FilePath* generated_name); // Persist the automatic opening preference. void SaveAutoOpens(); @@ -475,21 +479,21 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // real file name. // Invoked on the file thread. void ProceedWithFinishedDangerousDownload(int64 download_handle, - const std::wstring& path, - const std::wstring& original_name); + const FilePath& path, + const FilePath& original_name); // Invoked on the UI thread when a dangerous downloaded file has been renamed. void DangerousDownloadRenamed(int64 download_handle, bool success, - const std::wstring& new_path, + const FilePath& new_path, int new_path_uniquifier); // Checks whether a file represents a risk if downloaded. - bool IsDangerous(const std::wstring& file_name); + bool IsDangerous(const FilePath& file_name); // Changes the paths and file name of the specified |download|, propagating // the change to the history system. - void RenameDownload(DownloadItem* download, const std::wstring& new_path); + void RenameDownload(DownloadItem* download, const FilePath& new_path); // 'downloads_' is map of all downloads in this profile. The key is the handle // returned by the history system, which is unique across sessions. This map @@ -549,13 +553,13 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // The user's last choice for download directory. This is only used when the // user wants us to prompt for a save location for each download. - std::wstring last_download_path_; + FilePath last_download_path_; // Set of file extensions to open at download completion. - std::set<std::wstring> auto_open_; + std::set<FilePath::StringType> auto_open_; // Set of file extensions that are executables and shouldn't be auto opened. - std::set<std::wstring> exe_types_; + std::set<FilePath::StringType> exe_types_; // Keep track of downloads that are completed before the user selects the // destination, so that observers are appropriately notified of completion diff --git a/chrome/browser/download/download_manager_unittest.cc b/chrome/browser/download/download_manager_unittest.cc index 21190eed..eef4e86 100644 --- a/chrome/browser/download/download_manager_unittest.cc +++ b/chrome/browser/download/download_manager_unittest.cc @@ -19,12 +19,14 @@ class DownloadManagerTest : public testing::Test { void GetGeneratedFilename(const std::string& content_disposition, const std::wstring& url, const std::string& mime_type, - std::wstring* generated_name) { + std::wstring* generated_name_string) { DownloadCreateInfo info; info.content_disposition = content_disposition; info.url = url; info.mime_type = mime_type; - download_manager_->GenerateFilename(&info, generated_name); + FilePath generated_name; + download_manager_->GenerateFilename(&info, &generated_name); + *generated_name_string = generated_name.ToWStringHack(); } protected: @@ -330,53 +332,53 @@ TEST_F(DownloadManagerTest, TestDownloadFilename) { namespace { const struct { - const wchar_t* path; + const FilePath::CharType* path; const char* mime_type; - const wchar_t* expected_path; + const FilePath::CharType* expected_path; } kSafeFilenameCases[] = { - { L"C:\\foo\\bar.htm", + { FILE_PATH_LITERAL("C:\\foo\\bar.htm"), "text/html", - L"C:\\foo\\bar.htm" }, - { L"C:\\foo\\bar.html", + FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, + { FILE_PATH_LITERAL("C:\\foo\\bar.html"), "text/html", - L"C:\\foo\\bar.html" }, - { L"C:\\foo\\bar", + FILE_PATH_LITERAL("C:\\foo\\bar.html") }, + { FILE_PATH_LITERAL("C:\\foo\\bar"), "text/html", - L"C:\\foo\\bar.htm" }, + FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, - { L"C:\\bar.html", + { FILE_PATH_LITERAL("C:\\bar.html"), "image/png", - L"C:\\bar.png" }, - { L"C:\\bar", + FILE_PATH_LITERAL("C:\\bar.png") }, + { FILE_PATH_LITERAL("C:\\bar"), "image/png", - L"C:\\bar.png" }, + FILE_PATH_LITERAL("C:\\bar.png") }, - { L"C:\\foo\\bar.exe", + { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), "text/html", - L"C:\\foo\\bar.htm" }, - { L"C:\\foo\\bar.exe", + FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, + { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), "image/gif", - L"C:\\foo\\bar.gif" }, + FILE_PATH_LITERAL("C:\\foo\\bar.gif") }, - { L"C:\\foo\\google.com", + { FILE_PATH_LITERAL("C:\\foo\\google.com"), "text/html", - L"C:\\foo\\google.htm" }, + FILE_PATH_LITERAL("C:\\foo\\google.htm") }, - { L"C:\\foo\\con.htm", + { FILE_PATH_LITERAL("C:\\foo\\con.htm"), "text/html", - L"C:\\foo\\_con.htm" }, - { L"C:\\foo\\con", + FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, + { FILE_PATH_LITERAL("C:\\foo\\con"), "text/html", - L"C:\\foo\\_con.htm" }, + FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, }; } // namespace TEST_F(DownloadManagerTest, GetSafeFilename) { for (int i = 0; i < arraysize(kSafeFilenameCases); ++i) { - std::wstring path(kSafeFilenameCases[i].path); + FilePath path(kSafeFilenameCases[i].path); download_manager_->GenerateSafeFilename(kSafeFilenameCases[i].mime_type, &path); - EXPECT_EQ(kSafeFilenameCases[i].expected_path, path); + EXPECT_EQ(kSafeFilenameCases[i].expected_path, path.value()); } } diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 5af7c47..e264987 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -47,7 +47,7 @@ bool BaseContextMenu::IsItemChecked(int id) const { case OPEN_WHEN_COMPLETE: return download_->open_when_complete(); case ALWAYS_OPEN_TYPE: { - const std::wstring extension = + const FilePath::StringType extension = file_util::GetFileExtensionFromPath(download_->full_path()); return download_->manager()->ShouldOpenFileExtension(extension); } @@ -115,17 +115,17 @@ void BaseContextMenu::ExecuteCommand(int id) { scw.WriteText(download_->url()); break; case COPY_PATH: - scw.WriteText(download_->full_path()); + scw.WriteText(download_->full_path().ToWStringHack()); break; case COPY_FILE: // TODO(paulg): Move to OSExchangeData when implementing drag and drop? - scw.WriteFile(download_->full_path()); + scw.WriteFile(download_->full_path().ToWStringHack()); break; case OPEN_WHEN_COMPLETE: OpenDownload(download_); break; case ALWAYS_OPEN_TYPE: { - const std::wstring extension = + const FilePath::StringType extension = file_util::GetFileExtensionFromPath(download_->full_path()); download_->manager()->OpenFilesOfExtension( extension, !IsItemChecked(ALWAYS_OPEN_TYPE)); @@ -221,11 +221,11 @@ DownloadDestinationContextMenu::~DownloadDestinationContextMenu() { // Download opening ------------------------------------------------------------ bool CanOpenDownload(DownloadItem* download) { - std::wstring file_to_use = download->full_path(); - if (!download->original_name().empty()) + FilePath file_to_use = download->full_path(); + if (!download->original_name().value().empty()) file_to_use = download->original_name(); - const std::wstring extension = + const FilePath::StringType extension = file_util::GetFileExtensionFromPath(file_to_use); return !download->manager()->IsExecutable(extension); } @@ -416,8 +416,9 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) { // Set up our OLE machinery scoped_refptr<OSExchangeData> data(new OSExchangeData); if (icon) - drag_utils::CreateDragImageForFile(download->file_name(), icon, data); - data->SetFilename(download->full_path()); + drag_utils::CreateDragImageForFile(download->file_name().ToWStringHack(), + icon, data); + data->SetFilename(download->full_path().ToWStringHack()); scoped_refptr<BaseDragSource> drag_source(new BaseDragSource); // Run the drag and drop loop @@ -426,6 +427,4 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) { &effects); } - } // namespace download_util - diff --git a/chrome/browser/download/save_file.cc b/chrome/browser/download/save_file.cc index cc6315c..b889bd2 100644 --- a/chrome/browser/download/save_file.cc +++ b/chrome/browser/download/save_file.cc @@ -101,7 +101,7 @@ bool SaveFile::Open(const char* open_mode) { // Sets the zone to tell Windows that this file comes from the Internet. // We ignore the return value because a failure is not fatal. // TODO(port): Similarly mark on Mac. - win_util::SetInternetZoneIdentifier(full_path_); + win_util::SetInternetZoneIdentifier(FilePath::FromWStringHack(full_path_)); #endif return true; } diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 809ee17..a67d890 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -177,8 +177,9 @@ bool SavePackage::Init() { } // Create the fake DownloadItem and display the view. - download_ = new DownloadItem(1, saved_main_file_path_, 0, page_url_, - std::wstring(), Time::Now(), 0, -1, -1, false); + download_ = new DownloadItem(1, + FilePath::FromWStringHack(saved_main_file_path_), 0, page_url_, + FilePath(), Time::Now(), 0, -1, -1, false); download_->set_manager(web_contents_->profile()->GetDownloadManager()); DownloadShelfView* shelf = web_contents_->GetDownloadShelfView(); shelf->AddDownloadView(new DownloadItemView( @@ -951,8 +952,9 @@ bool SavePackage::GetSaveInfo(const std::wstring& suggest_name, DCHECK(download_manager); // Ensure the filename is safe. - download_manager->GenerateSafeFilename(param->current_tab_mime_type, - ¶m->saved_main_file_path); + FilePath path; + download_manager->GenerateSafeFilename(param->current_tab_mime_type, &path); + param->saved_main_file_path = path.ToWStringHack(); // The option index is not zero-based. DCHECK(index > 0 && index < 3); diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc index f1dcbce..d6f77b6 100644 --- a/chrome/browser/history/download_database.cc +++ b/chrome/browser/history/download_database.cc @@ -69,7 +69,8 @@ void DownloadDatabase::QueryDownloads(std::vector<DownloadCreateInfo>* results) while (statement->step() == SQLITE_ROW) { DownloadCreateInfo info; info.db_handle = statement->column_int64(0); - statement->column_string16(1, &info.path); + std::wstring path_str = info.path.ToWStringHack(); + statement->column_string16(1, &path_str); statement->column_string16(2, &info.url); info.start_time = Time::FromTimeT(statement->column_int64(3)); info.received_bytes = statement->column_int64(4); @@ -117,7 +118,7 @@ int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) { if (!statement.is_valid()) return 0; - statement->bind_wstring(0, info.path); + statement->bind_wstring(0, info.path.ToWStringHack()); statement->bind_wstring(1, info.url); statement->bind_int64(2, info.start_time.ToTimeT()); statement->bind_int64(3, info.received_bytes); diff --git a/chrome/browser/history/download_types.h b/chrome/browser/history/download_types.h index 61a6d83..e520ff6 100644 --- a/chrome/browser/history/download_types.h +++ b/chrome/browser/history/download_types.h @@ -11,6 +11,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/file_path.h" #include "base/time.h" // Used for informing the download database of a new download, where we don't @@ -18,7 +19,7 @@ // vector of these structs for passing us the state of all downloads at // initialization time (see DownloadQueryInfo below). struct DownloadCreateInfo { - DownloadCreateInfo(const std::wstring& path, + DownloadCreateInfo(const FilePath& path, const std::wstring& url, base::Time start_time, int64 received_bytes, @@ -44,9 +45,9 @@ struct DownloadCreateInfo { DownloadCreateInfo() : download_id(-1) {} // DownloadItem fields - std::wstring path; + FilePath path; std::wstring url; - std::wstring suggested_path; + FilePath suggested_path; // A number that should be added to the suggested path to make it unique. // 0 means no number should be appended. Not actually stored in the db. int path_uniquifier; @@ -65,7 +66,7 @@ struct DownloadCreateInfo { // Whether this download is potentially dangerous (ex: exe, dll, ...). bool is_dangerous; // The original name for a dangerous download. - std::wstring original_name; + FilePath original_name; }; #endif // CHROME_BROWSER_DOWNLOAD_TYPES_H__ diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc index 11b58b0..2f10adb 100644 --- a/chrome/browser/history/history_unittest.cc +++ b/chrome/browser/history/history_unittest.cc @@ -193,8 +193,8 @@ class HistoryTest : public testing::Test { } int64 AddDownload(int32 state, const Time& time) { - DownloadCreateInfo download(L"foo-path", L"foo-url", time, - 0, 512, state, 0); + DownloadCreateInfo download(FilePath(FILE_PATH_LITERAL("foo-path")), + L"foo-url", time, 0, 512, state, 0); return db_->CreateDownload(download); } diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc index f3e4a2a..6579e55 100644 --- a/chrome/browser/views/download_item_view.cc +++ b/chrome/browser/views/download_item_view.cc @@ -201,7 +201,7 @@ DownloadItemView::DownloadItemView(DownloadItem* download, discard_button_->set_enforce_dlu_min_size(false); AddChildView(save_button_); AddChildView(discard_button_); - std::wstring file_name = download->original_name(); + std::wstring file_name = download->original_name().ToWStringHack(); // Ensure the file name is not too long. @@ -457,7 +457,7 @@ void DownloadItemView::Paint(ChromeCanvas* canvas) { // Note that in dangerous mode we use a label (as the text is multi-line). if (!IsDangerousMode()) { std::wstring filename = - gfx::ElideFilename(download_->GetFileName(), + gfx::ElideFilename(download_->GetFileName().ToWStringHack(), font_, kTextWidth); @@ -487,7 +487,7 @@ void DownloadItemView::Paint(ChromeCanvas* canvas) { // Paint the icon. IconManager* im = g_browser_process->icon_manager(); SkBitmap* icon = IsDangerousMode() ? warning_icon_ : - im->LookupIcon(download_->full_path(), IconLoader::SMALL); + im->LookupIcon(download_->full_path().ToWStringHack(), IconLoader::SMALL); // We count on the fact that the icon manager will cache the icons and if one // is available, it will be cached here. We *don't* want to request the icon @@ -716,7 +716,7 @@ bool DownloadItemView::OnMouseDragged(const views::MouseEvent& event) { if (dragging_) { if (download_->state() == DownloadItem::COMPLETE) { IconManager* im = g_browser_process->icon_manager(); - SkBitmap* icon = im->LookupIcon(download_->full_path(), + SkBitmap* icon = im->LookupIcon(download_->full_path().ToWStringHack(), IconLoader::SMALL); if (icon) download_util::DragDownload(download_, icon); @@ -750,7 +750,7 @@ void DownloadItemView::OnExtractIconComplete(IconManager::Handle handle, void DownloadItemView::LoadIcon() { IconManager* im = g_browser_process->icon_manager(); - im->LoadIcon(download_->full_path(), IconLoader::SMALL, + im->LoadIcon(download_->full_path().ToWStringHack(), IconLoader::SMALL, &icon_consumer_, NewCallback(this, &DownloadItemView::OnExtractIconComplete)); } diff --git a/chrome/browser/views/download_tab_view.cc b/chrome/browser/views/download_tab_view.cc index b0d7c77..474f0a7 100644 --- a/chrome/browser/views/download_tab_view.cc +++ b/chrome/browser/views/download_tab_view.cc @@ -285,7 +285,8 @@ void DownloadItemTabView::LayoutComplete() { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); ChromeFont font = rb.GetFont(ResourceBundle::WebFont); file_name_->SetText( - gfx::ElideFilename(model_->GetFileName(), font, kFilenameSize)); + gfx::ElideFilename(model_->GetFileName().ToWStringHack(), font, + kFilenameSize)); gfx::Size file_name_size = file_name_->GetPreferredSize(); @@ -339,7 +340,7 @@ void DownloadItemTabView::LayoutCancelled() { // File name and URL, truncated to show cancelled status ResourceBundle& rb = ResourceBundle::GetSharedInstance(); ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - file_name_->SetText(gfx::ElideFilename(model_->GetFileName(), + file_name_->SetText(gfx::ElideFilename(model_->GetFileName().ToWStringHack(), font, kFilenameSize)); gfx::Size file_name_size = file_name_->GetPreferredSize(); @@ -430,7 +431,7 @@ void DownloadItemTabView::LayoutInProgress() { // File name and URL, truncated to show progress status ResourceBundle& rb = ResourceBundle::GetSharedInstance(); ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - file_name_->SetText(gfx::ElideFilename(model_->GetFileName(), + file_name_->SetText(gfx::ElideFilename(model_->GetFileName().ToWStringHack(), font, kFilenameSize)); gfx::Size file_name_size = file_name_->GetPreferredSize(); @@ -590,7 +591,7 @@ void DownloadItemTabView::LayoutPromptDangerousDownload() { // Warning message and URL. std::wstring file_name; - ElideString(model_->original_name(), kFileNameMaxLength, &file_name); + ElideString(model_->original_name().ToWStringHack(), kFileNameMaxLength, &file_name); dangerous_download_warning_->SetText( l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, file_name)); gfx::Size warning_size = dangerous_download_warning_->GetPreferredSize(); @@ -1074,7 +1075,8 @@ void DownloadTabView::SetDownloads(std::vector<DownloadItem*>& downloads) { SkBitmap* DownloadTabView::LookupIcon(DownloadItem* download) { IconManager* im = g_browser_process->icon_manager(); // Fast look up. - SkBitmap* icon = im->LookupIcon(download->full_path(), IconLoader::NORMAL); + SkBitmap* icon = im->LookupIcon(download->full_path().ToWStringHack(), + IconLoader::NORMAL); // Expensive look up. if (!icon) @@ -1089,7 +1091,7 @@ SkBitmap* DownloadTabView::LookupIcon(DownloadItem* download) { void DownloadTabView::LoadIcon(DownloadItem* download) { IconManager* im = g_browser_process->icon_manager(); IconManager::Handle h = - im->LoadIcon(download->full_path(), IconLoader::NORMAL, + im->LoadIcon(download->full_path().ToWStringHack(), IconLoader::NORMAL, &icon_consumer_, NewCallback(this, &DownloadTabView::OnExtractIconComplete)); icon_consumer_.SetClientData(im, h, download); diff --git a/chrome/common/win_safe_util.cc b/chrome/common/win_safe_util.cc index fd1658d..70782ee 100644 --- a/chrome/common/win_safe_util.cc +++ b/chrome/common/win_safe_util.cc @@ -8,6 +8,7 @@ #include "chrome/common/win_safe_util.h" +#include "base/file_path.h" #include "base/logging.h" #include "base/path_service.h" #include "base/string_util.h" @@ -88,7 +89,7 @@ public: // more information at: // http://msdn2.microsoft.com/en-us/library/ms647048.aspx bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, - const std::wstring& full_path, + const FilePath& full_path, const std::wstring& source_url, bool ask_for_app) { ATL::CComPtr<IAttachmentExecute> attachment_services; @@ -118,7 +119,7 @@ bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, // what the documentation calls evidence. Which we provide now: // // Set the file itself as evidence. - hr = attachment_services->SetLocalPath(full_path.c_str()); + hr = attachment_services->SetLocalPath(full_path.value().c_str()); if (FAILED(hr)) return false; // Set the origin URL as evidence. @@ -161,9 +162,9 @@ bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, return OpenItemViaShellNoZoneCheck(full_path, ask_for_app); } -bool SetInternetZoneIdentifier(const std::wstring& full_path) { +bool SetInternetZoneIdentifier(const FilePath& full_path) { const DWORD kShare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - std::wstring path = full_path + L":Zone.Identifier"; + std::wstring path = full_path.value() + L":Zone.Identifier"; HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, kShare, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == file) diff --git a/chrome/common/win_safe_util.h b/chrome/common/win_safe_util.h index b21a0ec..58af7d4 100644 --- a/chrome/common/win_safe_util.h +++ b/chrome/common/win_safe_util.h @@ -8,6 +8,8 @@ #include <string> #include <windows.h> +class FilePath; + namespace win_util { // Open or run a downloaded file via the Windows shell, possibly showing first @@ -35,14 +37,14 @@ namespace win_util { // dialog, for an application to use if 'ask_for_app' is true. // Returns 'true' on successful open, 'false' otherwise. bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, - const std::wstring& full_path, + const FilePath& full_path, const std::wstring& source_url, bool ask_for_app); // Sets the Zone Identifier on the file to "Internet" (3). Returns true if the // function succeeds, false otherwise. A failure is expected on system where // the Zone Identifier is not supported, like a machine with a FAT32 filesystem. // It should not be considered fatal. -bool SetInternetZoneIdentifier(const std::wstring& full_path); +bool SetInternetZoneIdentifier(const FilePath& full_path); } // namespace win_util diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc index b14e0c9..1c552a2 100644 --- a/chrome/common/win_util.cc +++ b/chrome/common/win_util.cc @@ -223,33 +223,33 @@ void ShowItemInFolder(const std::wstring& full_path) { // Open an item via a shell execute command. Error code checking and casting // explanation: http://msdn2.microsoft.com/en-us/library/ms647732.aspx -bool OpenItemViaShell(const std::wstring& full_path, bool ask_for_app) { +bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app) { HINSTANCE h = ::ShellExecuteW( - NULL, NULL, full_path.c_str(), NULL, - file_util::GetDirectoryFromPath(full_path).c_str(), SW_SHOWNORMAL); + NULL, NULL, full_path.value().c_str(), NULL, + full_path.DirName().value().c_str(), SW_SHOWNORMAL); LONG_PTR error = reinterpret_cast<LONG_PTR>(h); if (error > 32) return true; if ((error == SE_ERR_NOASSOC) && ask_for_app) - return OpenItemWithExternalApp(full_path); + return OpenItemWithExternalApp(full_path.value()); return false; } -bool OpenItemViaShellNoZoneCheck(const std::wstring& full_path, +bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, bool ask_for_app) { SHELLEXECUTEINFO sei = { sizeof(sei) }; sei.fMask = SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT; sei.nShow = SW_SHOWNORMAL; sei.lpVerb = NULL; - sei.lpFile = full_path.c_str(); + sei.lpFile = full_path.value().c_str(); if (::ShellExecuteExW(&sei)) return true; LONG_PTR error = reinterpret_cast<LONG_PTR>(sei.hInstApp); if ((error == SE_ERR_NOASSOC) && ask_for_app) - return OpenItemWithExternalApp(full_path); + return OpenItemWithExternalApp(full_path.value()); return false; } diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h index 112f1bd..5487ef3 100644 --- a/chrome/common/win_util.h +++ b/chrome/common/win_util.h @@ -15,6 +15,8 @@ #include "base/scoped_handle.h" #include "chrome/common/gfx/chrome_font.h" +class FilePath; + namespace win_util { // Import ScopedHandle and friends into this namespace for backwards @@ -112,12 +114,12 @@ void ShowItemInFolder(const std::wstring& full_path); // ask the user, via the Windows "Open With" dialog, for an application to use // if 'ask_for_app' is true. // Returns 'true' on successful open, 'false' otherwise. -bool OpenItemViaShell(const std::wstring& full_path, bool ask_for_app); +bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app); // The download manager now writes the alternate data stream with the // zone on all downloads. This function is equivalent to OpenItemViaShell // without showing the zone warning dialog. -bool OpenItemViaShellNoZoneCheck(const std::wstring& full_path, +bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, bool ask_for_app); // Ask the user, via the Windows "Open With" dialog, for an application to use |