| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <time.h> | 5 #include <time.h> |
| 6 | 6 |
| 7 #include "chrome/browser/download/download_manager.h" | 7 #include "chrome/browser/download/download_manager.h" |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 static const int kUpdateTimeMs = 1000; | 58 static const int kUpdateTimeMs = 1000; |
| 59 | 59 |
| 60 // Our download table ID starts at 1, so we use 0 to represent a download that | 60 // Our download table ID starts at 1, so we use 0 to represent a download that |
| 61 // has started, but has not yet had its data persisted in the table. We use fake | 61 // has started, but has not yet had its data persisted in the table. We use fake |
| 62 // database handles in incognito mode starting at -1 and progressively getting | 62 // database handles in incognito mode starting at -1 and progressively getting |
| 63 // more negative. | 63 // more negative. |
| 64 static const int kUninitializedHandle = 0; | 64 static const int kUninitializedHandle = 0; |
| 65 | 65 |
| 66 // Appends the passed the number between parenthesis the path before the | 66 // Appends the passed the number between parenthesis the path before the |
| 67 // extension. | 67 // extension. |
| 68 static void AppendNumberToPath(std::wstring* path, int number) { | 68 static void AppendNumberToPath(FilePath* path, int number) { |
| 69 file_util::InsertBeforeExtension(path, StringPrintf(L" (%d)", number)); | 69 file_util::InsertBeforeExtension(path, |
| 70 StringPrintf(FILE_PATH_LITERAL(" (%d)"), number)); |
| 70 } | 71 } |
| 71 | 72 |
| 72 // Attempts to find a number that can be appended to that path to make it | 73 // Attempts to find a number that can be appended to that path to make it |
| 73 // unique. If |path| does not exist, 0 is returned. If it fails to find such | 74 // unique. If |path| does not exist, 0 is returned. If it fails to find such |
| 74 // a number, -1 is returned. | 75 // a number, -1 is returned. |
| 75 static int GetUniquePathNumber(const std::wstring& path) { | 76 static int GetUniquePathNumber(const FilePath& path) { |
| 76 const int kMaxAttempts = 100; | 77 const int kMaxAttempts = 100; |
| 77 | 78 |
| 78 if (!file_util::PathExists(path)) | 79 if (!file_util::PathExists(path)) |
| 79 return 0; | 80 return 0; |
| 80 | 81 |
| 81 std::wstring new_path; | 82 FilePath new_path; |
| 82 for (int count = 1; count <= kMaxAttempts; ++count) { | 83 for (int count = 1; count <= kMaxAttempts; ++count) { |
| 83 new_path.assign(path); | 84 new_path = FilePath(path); |
| 84 AppendNumberToPath(&new_path, count); | 85 AppendNumberToPath(&new_path, count); |
| 85 | 86 |
| 86 if (!file_util::PathExists(new_path)) | 87 if (!file_util::PathExists(new_path)) |
| 87 return count; | 88 return count; |
| 88 } | 89 } |
| 89 | 90 |
| 90 return -1; | 91 return -1; |
| 91 } | 92 } |
| 92 | 93 |
| 93 static bool DownloadPathIsDangerous(const std::wstring& download_path) { | 94 static bool DownloadPathIsDangerous(const FilePath& download_path) { |
| 94 std::wstring desktop_dir; | 95 FilePath desktop_dir; |
| 95 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_dir)) { | 96 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_dir)) { |
| 96 NOTREACHED(); | 97 NOTREACHED(); |
| 97 return false; | 98 return false; |
| 98 } | 99 } |
| 99 return (download_path == desktop_dir); | 100 return (download_path == desktop_dir); |
| 100 } | 101 } |
| 101 | 102 |
| 102 // DownloadItem implementation ------------------------------------------------- | 103 // DownloadItem implementation ------------------------------------------------- |
| 103 | 104 |
| 104 // Constructor for reading from the history service. | 105 // Constructor for reading from the history service. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 119 open_when_complete_(false), | 120 open_when_complete_(false), |
| 120 render_process_id_(-1), | 121 render_process_id_(-1), |
| 121 request_id_(-1) { | 122 request_id_(-1) { |
| 122 if (state_ == IN_PROGRESS) | 123 if (state_ == IN_PROGRESS) |
| 123 state_ = CANCELLED; | 124 state_ = CANCELLED; |
| 124 Init(false /* don't start progress timer */); | 125 Init(false /* don't start progress timer */); |
| 125 } | 126 } |
| 126 | 127 |
| 127 // Constructor for DownloadItem created via user action in the main thread. | 128 // Constructor for DownloadItem created via user action in the main thread. |
| 128 DownloadItem::DownloadItem(int32 download_id, | 129 DownloadItem::DownloadItem(int32 download_id, |
| 129 const std::wstring& path, | 130 const FilePath& path, |
| 130 int path_uniquifier, | 131 int path_uniquifier, |
| 131 const std::wstring& url, | 132 const std::wstring& url, |
| 132 const std::wstring& original_name, | 133 const FilePath& original_name, |
| 133 const Time start_time, | 134 const Time start_time, |
| 134 int64 download_size, | 135 int64 download_size, |
| 135 int render_process_id, | 136 int render_process_id, |
| 136 int request_id, | 137 int request_id, |
| 137 bool is_dangerous) | 138 bool is_dangerous) |
| 138 : id_(download_id), | 139 : id_(download_id), |
| 139 full_path_(path), | 140 full_path_(path), |
| 140 path_uniquifier_(path_uniquifier), | 141 path_uniquifier_(path_uniquifier), |
| 141 url_(url), | 142 url_(url), |
| 142 original_name_(original_name), | 143 original_name_(original_name), |
| 143 total_bytes_(download_size), | 144 total_bytes_(download_size), |
| 144 received_bytes_(0), | 145 received_bytes_(0), |
| 145 start_tick_(GetTickCount()), | 146 start_tick_(GetTickCount()), |
| 146 state_(IN_PROGRESS), | 147 state_(IN_PROGRESS), |
| 147 start_time_(start_time), | 148 start_time_(start_time), |
| 148 db_handle_(kUninitializedHandle), | 149 db_handle_(kUninitializedHandle), |
| 149 manager_(NULL), | 150 manager_(NULL), |
| 150 safety_state_(is_dangerous ? DANGEROUS : SAFE), | 151 safety_state_(is_dangerous ? DANGEROUS : SAFE), |
| 151 is_paused_(false), | 152 is_paused_(false), |
| 152 open_when_complete_(false), | 153 open_when_complete_(false), |
| 153 render_process_id_(render_process_id), | 154 render_process_id_(render_process_id), |
| 154 request_id_(request_id) { | 155 request_id_(request_id) { |
| 155 Init(true /* start progress timer */); | 156 Init(true /* start progress timer */); |
| 156 } | 157 } |
| 157 | 158 |
| 158 void DownloadItem::Init(bool start_timer) { | 159 void DownloadItem::Init(bool start_timer) { |
| 159 file_name_ = file_util::GetFilenameFromPath(full_path_); | 160 file_name_ = full_path_.BaseName(); |
| 160 if (start_timer) | 161 if (start_timer) |
| 161 StartProgressTimer(); | 162 StartProgressTimer(); |
| 162 } | 163 } |
| 163 | 164 |
| 164 DownloadItem::~DownloadItem() { | 165 DownloadItem::~DownloadItem() { |
| 165 state_ = REMOVING; | 166 state_ = REMOVING; |
| 166 UpdateObservers(); | 167 UpdateObservers(); |
| 167 } | 168 } |
| 168 | 169 |
| 169 void DownloadItem::AddObserver(Observer* observer) { | 170 void DownloadItem::AddObserver(Observer* observer) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 return diff == 0 ? 0 : received_bytes_ * 1000 / diff; | 255 return diff == 0 ? 0 : received_bytes_ * 1000 / diff; |
| 255 } | 256 } |
| 256 | 257 |
| 257 int DownloadItem::PercentComplete() const { | 258 int DownloadItem::PercentComplete() const { |
| 258 int percent = -1; | 259 int percent = -1; |
| 259 if (total_bytes_ > 0) | 260 if (total_bytes_ > 0) |
| 260 percent = static_cast<int>(received_bytes_ * 100.0 / total_bytes_); | 261 percent = static_cast<int>(received_bytes_ * 100.0 / total_bytes_); |
| 261 return percent; | 262 return percent; |
| 262 } | 263 } |
| 263 | 264 |
| 264 void DownloadItem::Rename(const std::wstring& full_path) { | 265 void DownloadItem::Rename(const FilePath& full_path) { |
| 265 DCHECK(!full_path.empty()); | 266 DCHECK(!full_path.empty()); |
| 266 full_path_ = full_path; | 267 full_path_ = full_path; |
| 267 file_name_ = file_util::GetFilenameFromPath(full_path_); | 268 file_name_ = full_path_.BaseName(); |
| 268 } | 269 } |
| 269 | 270 |
| 270 void DownloadItem::TogglePause() { | 271 void DownloadItem::TogglePause() { |
| 271 DCHECK(state_ == IN_PROGRESS); | 272 DCHECK(state_ == IN_PROGRESS); |
| 272 manager_->PauseDownload(id_, !is_paused_); | 273 manager_->PauseDownload(id_, !is_paused_); |
| 273 is_paused_ = !is_paused_; | 274 is_paused_ = !is_paused_; |
| 274 UpdateObservers(); | 275 UpdateObservers(); |
| 275 } | 276 } |
| 276 | 277 |
| 277 std::wstring DownloadItem::GetFileName() const { | 278 FilePath DownloadItem::GetFileName() const { |
| 278 if (safety_state_ == DownloadItem::SAFE) | 279 if (safety_state_ == DownloadItem::SAFE) |
| 279 return file_name_; | 280 return file_name_; |
| 280 if (path_uniquifier_ > 0) { | 281 if (path_uniquifier_ > 0) { |
| 281 std::wstring name(original_name_); | 282 FilePath name(original_name_); |
| 282 AppendNumberToPath(&name, path_uniquifier_); | 283 AppendNumberToPath(&name, path_uniquifier_); |
| 283 return name; | 284 return name; |
| 284 } | 285 } |
| 285 return original_name_; | 286 return original_name_; |
| 286 } | 287 } |
| 287 | 288 |
| 288 // DownloadManager implementation ---------------------------------------------- | 289 // DownloadManager implementation ---------------------------------------------- |
| 289 | 290 |
| 290 // static | 291 // static |
| 291 void DownloadManager::RegisterUserPrefs(PrefService* prefs) { | 292 void DownloadManager::RegisterUserPrefs(PrefService* prefs) { |
| 292 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false); | 293 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false); |
| 293 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, L""); | 294 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, L""); |
| 294 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); | 295 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); |
| 295 | 296 |
| 296 // The default download path is userprofile\download. | 297 // The default download path is userprofile\download. |
| 297 std::wstring default_download_path; | 298 FilePath default_download_path; |
| 298 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, | 299 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, |
| 299 &default_download_path)) { | 300 &default_download_path)) { |
| 300 NOTREACHED(); | 301 NOTREACHED(); |
| 301 } | 302 } |
| 302 prefs->RegisterStringPref(prefs::kDownloadDefaultDirectory, | 303 prefs->RegisterStringPref(prefs::kDownloadDefaultDirectory, |
| 303 default_download_path); | 304 default_download_path.ToWStringHack()); |
| 304 | 305 |
| 305 // If the download path is dangerous we forcefully reset it. But if we do | 306 // If the download path is dangerous we forcefully reset it. But if we do |
| 306 // so we set a flag to make sure we only do it once, to avoid fighting | 307 // so we set a flag to make sure we only do it once, to avoid fighting |
| 307 // the user if he really wants it on an unsafe place such as the desktop. | 308 // the user if he really wants it on an unsafe place such as the desktop. |
| 308 | 309 |
| 309 if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) { | 310 if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) { |
| 310 std::wstring current_download_dir = | 311 FilePath current_download_dir = FilePath::FromWStringHack( |
| 311 prefs->GetString(prefs::kDownloadDefaultDirectory); | 312 prefs->GetString(prefs::kDownloadDefaultDirectory)); |
| 312 if (DownloadPathIsDangerous(current_download_dir)) { | 313 if (DownloadPathIsDangerous(current_download_dir)) { |
| 313 prefs->SetString(prefs::kDownloadDefaultDirectory, | 314 prefs->SetString(prefs::kDownloadDefaultDirectory, |
| 314 default_download_path); | 315 default_download_path.ToWStringHack()); |
| 315 } | 316 } |
| 316 prefs->SetBoolean(prefs::kDownloadDirUpgraded, true); | 317 prefs->SetBoolean(prefs::kDownloadDirUpgraded, true); |
| 317 } | 318 } |
| 318 } | 319 } |
| 319 | 320 |
| 320 DownloadManager::DownloadManager() | 321 DownloadManager::DownloadManager() |
| 321 : shutdown_needed_(false), | 322 : shutdown_needed_(false), |
| 322 profile_(NULL), | 323 profile_(NULL), |
| 323 file_manager_(NULL), | 324 file_manager_(NULL), |
| 324 ui_loop_(MessageLoop::current()), | 325 ui_loop_(MessageLoop::current()), |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 return false; | 473 return false; |
| 473 } | 474 } |
| 474 | 475 |
| 475 // Get our user preference state. | 476 // Get our user preference state. |
| 476 PrefService* prefs = profile_->GetPrefs(); | 477 PrefService* prefs = profile_->GetPrefs(); |
| 477 DCHECK(prefs); | 478 DCHECK(prefs); |
| 478 prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL); | 479 prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL); |
| 479 | 480 |
| 480 download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); | 481 download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); |
| 481 | 482 |
| 483 // This variable is needed to resolve which CreateDirectory we want to point |
| 484 // to. Without it, the NewRunnableFunction cannot resolve the ambiguity. |
| 485 // TODO(estade): when file_util::CreateDirectory(wstring) is removed, |
| 486 // get rid of |CreateDirectoryPtr|. |
| 487 bool (*CreateDirectoryPtr)(const FilePath&) = &file_util::CreateDirectory; |
| 482 // Ensure that the download directory specified in the preferences exists. | 488 // Ensure that the download directory specified in the preferences exists. |
| 483 file_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 489 file_loop_->PostTask(FROM_HERE, NewRunnableFunction( |
| 484 file_manager_, &DownloadFileManager::CreateDirectory, *download_path_)); | 490 CreateDirectoryPtr, download_path())); |
| 485 | 491 |
| 486 // We store any file extension that should be opened automatically at | 492 // We store any file extension that should be opened automatically at |
| 487 // download completion in this pref. | 493 // download completion in this pref. |
| 488 download_util::InitializeExeTypes(&exe_types_); | 494 download_util::InitializeExeTypes(&exe_types_); |
| 489 | 495 |
| 490 std::wstring extensions_to_open = | 496 std::wstring extensions_to_open = |
| 491 prefs->GetString(prefs::kDownloadExtensionsToOpen); | 497 prefs->GetString(prefs::kDownloadExtensionsToOpen); |
| 492 std::vector<std::wstring> extensions; | 498 std::vector<std::wstring> extensions; |
| 493 SplitString(extensions_to_open, L':', &extensions); | 499 SplitString(extensions_to_open, L':', &extensions); |
| 494 for (size_t i = 0; i < extensions.size(); ++i) { | 500 for (size_t i = 0; i < extensions.size(); ++i) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 520 DCHECK(info); | 526 DCHECK(info); |
| 521 | 527 |
| 522 // Freeze the user's preference for showing a Save As dialog. We're going to | 528 // Freeze the user's preference for showing a Save As dialog. We're going to |
| 523 // bounce around a bunch of threads and we don't want to worry about race | 529 // bounce around a bunch of threads and we don't want to worry about race |
| 524 // conditions where the user changes this pref out from under us. | 530 // conditions where the user changes this pref out from under us. |
| 525 if (*prompt_for_download_) | 531 if (*prompt_for_download_) |
| 526 info->save_as = true; | 532 info->save_as = true; |
| 527 | 533 |
| 528 // Determine the proper path for a download, by choosing either the default | 534 // Determine the proper path for a download, by choosing either the default |
| 529 // download directory, or prompting the user. | 535 // download directory, or prompting the user. |
| 530 std::wstring generated_name; | 536 FilePath generated_name; |
| 531 GenerateFilename(info, &generated_name); | 537 GenerateFilename(info, &generated_name); |
| 532 if (info->save_as && !last_download_path_.empty()) | 538 if (info->save_as && !last_download_path_.empty()) |
| 533 info->suggested_path = last_download_path_; | 539 info->suggested_path = last_download_path_; |
| 534 else | 540 else |
| 535 info->suggested_path = *download_path_; | 541 info->suggested_path = download_path(); |
| 536 file_util::AppendToPath(&info->suggested_path, generated_name); | 542 info->suggested_path = info->suggested_path.Append(generated_name); |
| 537 | 543 |
| 538 if (!info->save_as) { | 544 if (!info->save_as) { |
| 539 // Let's check if this download is dangerous, based on its name. | 545 // Let's check if this download is dangerous, based on its name. |
| 540 const std::wstring filename = | 546 info->is_dangerous = IsDangerous(info->suggested_path.BaseName()); |
| 541 file_util::GetFilenameFromPath(info->suggested_path); | |
| 542 info->is_dangerous = IsDangerous(filename); | |
| 543 } | 547 } |
| 544 | 548 |
| 545 // We need to move over to the download thread because we don't want to stat | 549 // We need to move over to the download thread because we don't want to stat |
| 546 // the suggested path on the UI thread. | 550 // the suggested path on the UI thread. |
| 547 file_loop_->PostTask(FROM_HERE, | 551 file_loop_->PostTask(FROM_HERE, |
| 548 NewRunnableMethod(this, | 552 NewRunnableMethod(this, |
| 549 &DownloadManager::CheckIfSuggestedPathExists, | 553 &DownloadManager::CheckIfSuggestedPathExists, |
| 550 info)); | 554 info)); |
| 551 } | 555 } |
| 552 | 556 |
| 553 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { | 557 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { |
| 554 DCHECK(info); | 558 DCHECK(info); |
| 555 | 559 |
| 556 // Check writability of the suggested path. If we can't write to it, default | 560 // Check writability of the suggested path. If we can't write to it, default |
| 557 // to the user's "My Documents" directory. We'll prompt them in this case. | 561 // to the user's "My Documents" directory. We'll prompt them in this case. |
| 558 std::wstring dir = file_util::GetDirectoryFromPath(info->suggested_path); | 562 FilePath dir = info->suggested_path.DirName(); |
| 559 const std::wstring filename = | 563 FilePath filename = info->suggested_path.BaseName(); |
| 560 file_util::GetFilenameFromPath(info->suggested_path); | |
| 561 if (!file_util::PathIsWritable(dir)) { | 564 if (!file_util::PathIsWritable(dir)) { |
| 562 info->save_as = true; | 565 info->save_as = true; |
| 563 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); | 566 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); |
| 564 file_util::AppendToPath(&info->suggested_path, filename); | 567 info->suggested_path = info->suggested_path.Append(filename); |
| 565 } | 568 } |
| 566 | 569 |
| 567 info->path_uniquifier = GetUniquePathNumber(info->suggested_path); | 570 info->path_uniquifier = GetUniquePathNumber(info->suggested_path); |
| 568 | 571 |
| 569 // If the download is deemed dangerous, we'll use a temporary name for it. | 572 // If the download is deemed dangerous, we'll use a temporary name for it. |
| 570 if (info->is_dangerous) { | 573 if (info->is_dangerous) { |
| 571 info->original_name = file_util::GetFilenameFromPath(info->suggested_path); | 574 info->original_name = FilePath(info->suggested_path).BaseName(); |
| 572 // Create a temporary file to hold the file until the user approves its | 575 // Create a temporary file to hold the file until the user approves its |
| 573 // download. | 576 // download. |
| 574 std::wstring file_name; | 577 FilePath::StringType file_name; |
| 575 std::wstring path; | 578 FilePath path; |
| 576 while (path.empty()) { | 579 while (path.empty()) { |
| 577 SStringPrintf(&file_name, L"unconfirmed %d.download", | 580 SStringPrintf(&file_name, FILE_PATH_LITERAL("unconfirmed %d.download"), |
| 578 base::RandInt(0, 100000)); | 581 base::RandInt(0, 100000)); |
| 579 path = dir; | 582 path = dir.Append(file_name); |
| 580 file_util::AppendToPath(&path, file_name); | |
| 581 if (file_util::PathExists(path)) | 583 if (file_util::PathExists(path)) |
| 582 path.clear(); | 584 path = FilePath(); |
| 583 } | 585 } |
| 584 info->suggested_path = path; | 586 info->suggested_path = path; |
| 585 } else { | 587 } else { |
| 586 // We know the final path, build it if necessary. | 588 // We know the final path, build it if necessary. |
| 587 if (info->path_uniquifier > 0) { | 589 if (info->path_uniquifier > 0) { |
| 588 AppendNumberToPath(&(info->suggested_path), info->path_uniquifier); | 590 AppendNumberToPath(&(info->suggested_path), info->path_uniquifier); |
| 589 // Setting path_uniquifier to 0 to make sure we don't try to unique it | 591 // Setting path_uniquifier to 0 to make sure we don't try to unique it |
| 590 // later on. | 592 // later on. |
| 591 info->path_uniquifier = 0; | 593 info->path_uniquifier = 0; |
| 592 } else if (info->path_uniquifier == -1) { | 594 } else if (info->path_uniquifier == -1) { |
| 593 // We failed to find a unique path. We have to prompt the user. | 595 // We failed to find a unique path. We have to prompt the user. |
| 594 info->save_as = true; | 596 info->save_as = true; |
| 595 } | 597 } |
| 596 } | 598 } |
| 597 | 599 |
| 598 if (!info->save_as) { | 600 if (!info->save_as) { |
| 599 // Create an empty file at the suggested path so that we don't allocate the | 601 // Create an empty file at the suggested path so that we don't allocate the |
| 600 // same "non-existant" path to multiple downloads. | 602 // same "non-existant" path to multiple downloads. |
| 601 // See: http://code.google.com/p/chromium/issues/detail?id=3662 | 603 // See: http://code.google.com/p/chromium/issues/detail?id=3662 |
| 602 file_util::WriteFile(info->suggested_path, "", 0); | 604 file_util::WriteFile(info->suggested_path.ToWStringHack(), "", 0); |
| 603 } | 605 } |
| 604 | 606 |
| 605 // Now we return to the UI thread. | 607 // Now we return to the UI thread. |
| 606 ui_loop_->PostTask(FROM_HERE, | 608 ui_loop_->PostTask(FROM_HERE, |
| 607 NewRunnableMethod(this, | 609 NewRunnableMethod(this, |
| 608 &DownloadManager::OnPathExistenceAvailable, | 610 &DownloadManager::OnPathExistenceAvailable, |
| 609 info)); | 611 info)); |
| 610 } | 612 } |
| 611 | 613 |
| 612 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { | 614 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { |
| 613 DCHECK(MessageLoop::current() == ui_loop_); | 615 DCHECK(MessageLoop::current() == ui_loop_); |
| 614 DCHECK(info); | 616 DCHECK(info); |
| 615 | 617 |
| 616 if (info->save_as) { | 618 if (info->save_as) { |
| 617 // We must ask the user for the place to put the download. | 619 // We must ask the user for the place to put the download. |
| 618 if (!select_file_dialog_.get()) | 620 if (!select_file_dialog_.get()) |
| 619 select_file_dialog_ = SelectFileDialog::Create(this); | 621 select_file_dialog_ = SelectFileDialog::Create(this); |
| 620 | 622 |
| 621 WebContents* contents = tab_util::GetWebContentsByID( | 623 WebContents* contents = tab_util::GetWebContentsByID( |
| 622 info->render_process_id, info->render_view_id); | 624 info->render_process_id, info->render_view_id); |
| 623 std::wstring filter = win_util::GetFileFilterFromPath(info->suggested_path); | 625 std::wstring filter = |
| 626 win_util::GetFileFilterFromPath(info->suggested_path.value()); |
| 624 HWND owning_hwnd = | 627 HWND owning_hwnd = |
| 625 contents ? GetAncestor(contents->GetContainerHWND(), GA_ROOT) : NULL; | 628 contents ? GetAncestor(contents->GetContainerHWND(), GA_ROOT) : NULL; |
| 626 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, | 629 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, |
| 627 std::wstring(), info->suggested_path, | 630 std::wstring(), |
| 631 info->suggested_path.ToWStringHack(), |
| 628 filter, std::wstring(), | 632 filter, std::wstring(), |
| 629 owning_hwnd, info); | 633 owning_hwnd, info); |
| 630 } else { | 634 } else { |
| 631 // No prompting for download, just continue with the suggested name. | 635 // No prompting for download, just continue with the suggested name. |
| 632 ContinueStartDownload(info, info->suggested_path); | 636 ContinueStartDownload(info, info->suggested_path); |
| 633 } | 637 } |
| 634 } | 638 } |
| 635 | 639 |
| 636 void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info, | 640 void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info, |
| 637 const std::wstring& target_path) { | 641 const FilePath& target_path) { |
| 638 scoped_ptr<DownloadCreateInfo> infop(info); | 642 scoped_ptr<DownloadCreateInfo> infop(info); |
| 639 info->path = target_path; | 643 info->path = target_path; |
| 640 | 644 |
| 641 DownloadItem* download = NULL; | 645 DownloadItem* download = NULL; |
| 642 DownloadMap::iterator it = in_progress_.find(info->download_id); | 646 DownloadMap::iterator it = in_progress_.find(info->download_id); |
| 643 if (it == in_progress_.end()) { | 647 if (it == in_progress_.end()) { |
| 644 download = new DownloadItem(info->download_id, | 648 download = new DownloadItem(info->download_id, |
| 645 info->path, | 649 info->path, |
| 646 info->path_uniquifier, | 650 info->path_uniquifier, |
| 647 info->url, | 651 info->url, |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 // Open the download if the user or user prefs indicate it should be. | 806 // Open the download if the user or user prefs indicate it should be. |
| 803 const std::wstring extension = | 807 const std::wstring extension = |
| 804 file_util::GetFileExtensionFromPath(download->full_path()); | 808 file_util::GetFileExtensionFromPath(download->full_path()); |
| 805 if (download->open_when_complete() || ShouldOpenFileExtension(extension)) | 809 if (download->open_when_complete() || ShouldOpenFileExtension(extension)) |
| 806 OpenDownloadInShell(download, NULL); | 810 OpenDownloadInShell(download, NULL); |
| 807 } | 811 } |
| 808 | 812 |
| 809 // Called on the file thread. Renames the downloaded file to its original name. | 813 // Called on the file thread. Renames the downloaded file to its original name. |
| 810 void DownloadManager::ProceedWithFinishedDangerousDownload( | 814 void DownloadManager::ProceedWithFinishedDangerousDownload( |
| 811 int64 download_handle, | 815 int64 download_handle, |
| 812 const std::wstring& path, | 816 const FilePath& path, |
| 813 const std::wstring& original_name) { | 817 const FilePath& original_name) { |
| 814 bool success = false; | 818 bool success = false; |
| 815 std::wstring new_path = path; | 819 FilePath new_path; |
| 816 int uniquifier = 0; | 820 int uniquifier = 0; |
| 817 if (file_util::PathExists(path)) { | 821 if (file_util::PathExists(path)) { |
| 818 new_path = file_util::GetDirectoryFromPath(new_path); | 822 new_path = new_path.DirName().Append(original_name); |
| 819 file_util::AppendToPath(&new_path, original_name); | |
| 820 // Make our name unique at this point, as if a dangerous file is downloading | 823 // Make our name unique at this point, as if a dangerous file is downloading |
| 821 // and a 2nd download is started for a file with the same name, they would | 824 // and a 2nd download is started for a file with the same name, they would |
| 822 // have the same path. This is because we uniquify the name on download | 825 // have the same path. This is because we uniquify the name on download |
| 823 // start, and at that time the first file does not exists yet, so the second | 826 // start, and at that time the first file does not exists yet, so the second |
| 824 // file gets the same name. | 827 // file gets the same name. |
| 825 uniquifier = GetUniquePathNumber(new_path); | 828 uniquifier = GetUniquePathNumber(new_path); |
| 826 if (uniquifier > 0) | 829 if (uniquifier > 0) |
| 827 AppendNumberToPath(&new_path, uniquifier); | 830 AppendNumberToPath(&new_path, uniquifier); |
| 828 success = file_util::Move(path, new_path); | 831 success = file_util::Move(path, new_path); |
| 829 } else { | 832 } else { |
| 830 NOTREACHED(); | 833 NOTREACHED(); |
| 831 } | 834 } |
| 832 | 835 |
| 833 ui_loop_->PostTask(FROM_HERE, | 836 ui_loop_->PostTask(FROM_HERE, |
| 834 NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed, | 837 NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed, |
| 835 download_handle, success, new_path, uniquifier)); | 838 download_handle, success, new_path, uniquifier)); |
| 836 } | 839 } |
| 837 | 840 |
| 838 // Call from the file thread when the finished dangerous download was renamed. | 841 // Call from the file thread when the finished dangerous download was renamed. |
| 839 void DownloadManager::DangerousDownloadRenamed(int64 download_handle, | 842 void DownloadManager::DangerousDownloadRenamed(int64 download_handle, |
| 840 bool success, | 843 bool success, |
| 841 const std::wstring& new_path, | 844 const FilePath& new_path, |
| 842 int new_path_uniquifier) { | 845 int new_path_uniquifier) { |
| 843 DownloadMap::iterator it = downloads_.find(download_handle); | 846 DownloadMap::iterator it = downloads_.find(download_handle); |
| 844 if (it == downloads_.end()) { | 847 if (it == downloads_.end()) { |
| 845 NOTREACHED(); | 848 NOTREACHED(); |
| 846 return; | 849 return; |
| 847 } | 850 } |
| 848 | 851 |
| 849 DownloadItem* download = it->second; | 852 DownloadItem* download = it->second; |
| 850 // If we failed to rename the file, we'll just keep the name as is. | 853 // If we failed to rename the file, we'll just keep the name as is. |
| 851 if (success) { | 854 if (success) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 } | 933 } |
| 931 | 934 |
| 932 // static | 935 // static |
| 933 void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh, | 936 void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh, |
| 934 int render_process_id, | 937 int render_process_id, |
| 935 int request_id, | 938 int request_id, |
| 936 bool pause) { | 939 bool pause) { |
| 937 rdh->PauseRequest(render_process_id, request_id, pause); | 940 rdh->PauseRequest(render_process_id, request_id, pause); |
| 938 } | 941 } |
| 939 | 942 |
| 940 bool DownloadManager::IsDangerous(const std::wstring& file_name) { | 943 bool DownloadManager::IsDangerous(const FilePath& file_name) { |
| 941 // TODO(jcampan): Improve me. | 944 // TODO(jcampan): Improve me. |
| 942 return IsExecutable(file_util::GetFileExtensionFromPath(file_name)); | 945 return IsExecutable(file_util::GetFileExtensionFromPath(file_name)); |
| 943 } | 946 } |
| 944 | 947 |
| 945 void DownloadManager::RenameDownload(DownloadItem* download, | 948 void DownloadManager::RenameDownload(DownloadItem* download, |
| 946 const std::wstring& new_path) { | 949 const FilePath& new_path) { |
| 947 download->Rename(new_path); | 950 download->Rename(new_path); |
| 948 | 951 |
| 949 // Update the history. | 952 // Update the history. |
| 950 | 953 |
| 951 // No update necessary if the download was initiated while in incognito mode. | 954 // No update necessary if the download was initiated while in incognito mode. |
| 952 if (download->db_handle() <= kUninitializedHandle) | 955 if (download->db_handle() <= kUninitializedHandle) |
| 953 return; | 956 return; |
| 954 | 957 |
| 955 // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong. | 958 // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong. |
| 956 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 959 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 957 if (hs) | 960 if (hs) |
| 958 hs->UpdateDownloadPath(new_path, download->db_handle()); | 961 hs->UpdateDownloadPath(new_path.ToWStringHack(), download->db_handle()); |
| 959 } | 962 } |
| 960 | 963 |
| 961 void DownloadManager::RemoveDownload(int64 download_handle) { | 964 void DownloadManager::RemoveDownload(int64 download_handle) { |
| 962 DownloadMap::iterator it = downloads_.find(download_handle); | 965 DownloadMap::iterator it = downloads_.find(download_handle); |
| 963 if (it == downloads_.end()) | 966 if (it == downloads_.end()) |
| 964 return; | 967 return; |
| 965 | 968 |
| 966 // Make history update. | 969 // Make history update. |
| 967 DownloadItem* download = it->second; | 970 DownloadItem* download = it->second; |
| 968 RemoveDownloadFromHistory(download); | 971 RemoveDownloadFromHistory(download); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 Notify(NOTIFY_DOWNLOAD_START, NotificationService::AllSources(), | 1042 Notify(NOTIFY_DOWNLOAD_START, NotificationService::AllSources(), |
| 1040 NotificationService::NoDetails()); | 1043 NotificationService::NoDetails()); |
| 1041 } | 1044 } |
| 1042 | 1045 |
| 1043 void DownloadManager::NotifyAboutDownloadStop() { | 1046 void DownloadManager::NotifyAboutDownloadStop() { |
| 1044 NotificationService::current()-> | 1047 NotificationService::current()-> |
| 1045 Notify(NOTIFY_DOWNLOAD_STOP, NotificationService::AllSources(), | 1048 Notify(NOTIFY_DOWNLOAD_STOP, NotificationService::AllSources(), |
| 1046 NotificationService::NoDetails()); | 1049 NotificationService::NoDetails()); |
| 1047 } | 1050 } |
| 1048 | 1051 |
| 1049 void DownloadManager::GenerateExtension(const std::wstring& file_name, | 1052 void DownloadManager::GenerateExtension( |
| 1050 const std::string& mime_type, | 1053 const FilePath& file_name, |
| 1051 std::wstring* generated_extension) { | 1054 const std::string& mime_type, |
| 1055 FilePath::StringType* generated_extension) { |
| 1052 // We're worried about three things here: | 1056 // We're worried about three things here: |
| 1053 // | 1057 // |
| 1054 // 1) Security. Many sites let users upload content, such as buddy icons, to | 1058 // 1) Security. Many sites let users upload content, such as buddy icons, to |
| 1055 // their web sites. We want to mitigate the case where an attacker | 1059 // their web sites. We want to mitigate the case where an attacker |
| 1056 // supplies a malicious executable with an executable file extension but an | 1060 // supplies a malicious executable with an executable file extension but an |
| 1057 // honest site serves the content with a benign content type, such as | 1061 // honest site serves the content with a benign content type, such as |
| 1058 // image/jpeg. | 1062 // image/jpeg. |
| 1059 // | 1063 // |
| 1060 // 2) Usability. If the site fails to provide a file extension, we want to | 1064 // 2) Usability. If the site fails to provide a file extension, we want to |
| 1061 // guess a reasonable file extension based on the content type. | 1065 // guess a reasonable file extension based on the content type. |
| 1062 // | 1066 // |
| 1063 // 3) Shell integration. Some file extensions automatically integrate with | 1067 // 3) Shell integration. Some file extensions automatically integrate with |
| 1064 // the shell. We block these extensions to prevent a malicious web site | 1068 // the shell. We block these extensions to prevent a malicious web site |
| 1065 // from integrating with the user's shell. | 1069 // from integrating with the user's shell. |
| 1066 | 1070 |
| 1067 static const wchar_t default_extension[] = L"download"; | 1071 static const FilePath::CharType default_extension[] = |
| 1072 FILE_PATH_LITERAL("download"); |
| 1068 | 1073 |
| 1069 // See if our file name already contains an extension. | 1074 // See if our file name already contains an extension. |
| 1070 std::wstring extension(file_util::GetFileExtensionFromPath(file_name)); | 1075 FilePath::StringType extension( |
| 1076 file_util::GetFileExtensionFromPath(file_name)); |
| 1071 | 1077 |
| 1072 // Rename shell-integrated extensions. | 1078 // Rename shell-integrated extensions. |
| 1073 if (win_util::IsShellIntegratedExtension(extension)) | 1079 if (win_util::IsShellIntegratedExtension(extension)) |
| 1074 extension.assign(default_extension); | 1080 extension.assign(default_extension); |
| 1075 | 1081 |
| 1076 std::string mime_type_from_extension; | 1082 std::string mime_type_from_extension; |
| 1077 net::GetMimeTypeFromFile(file_name, &mime_type_from_extension); | 1083 net::GetMimeTypeFromFile(file_name.ToWStringHack(), |
| 1084 &mime_type_from_extension); |
| 1078 if (mime_type == mime_type_from_extension) { | 1085 if (mime_type == mime_type_from_extension) { |
| 1079 // The hinted extension matches the mime type. It looks like a winner. | 1086 // The hinted extension matches the mime type. It looks like a winner. |
| 1080 generated_extension->swap(extension); | 1087 generated_extension->swap(extension); |
| 1081 return; | 1088 return; |
| 1082 } | 1089 } |
| 1083 | 1090 |
| 1084 if (IsExecutable(extension) && !IsExecutableMimeType(mime_type)) { | 1091 if (IsExecutable(extension) && !IsExecutableMimeType(mime_type)) { |
| 1085 // We want to be careful about executable extensions. The worry here is | 1092 // We want to be careful about executable extensions. The worry here is |
| 1086 // that a trusted web site could be tricked into dropping an executable file | 1093 // that a trusted web site could be tricked into dropping an executable file |
| 1087 // on the user's filesystem. | 1094 // on the user's filesystem. |
| 1088 if (!net::GetPreferredExtensionForMimeType(mime_type, &extension)) { | 1095 if (!net::GetPreferredExtensionForMimeType(mime_type, &extension)) { |
| 1089 // We couldn't find a good extension for this content type. Use a dummy | 1096 // We couldn't find a good extension for this content type. Use a dummy |
| 1090 // extension instead. | 1097 // extension instead. |
| 1091 extension.assign(default_extension); | 1098 extension.assign(default_extension); |
| 1092 } | 1099 } |
| 1093 } | 1100 } |
| 1094 | 1101 |
| 1095 if (extension.empty()) { | 1102 if (extension.empty()) { |
| 1096 net::GetPreferredExtensionForMimeType(mime_type, &extension); | 1103 net::GetPreferredExtensionForMimeType(mime_type, &extension); |
| 1097 } else { | 1104 } else { |
| 1098 // Append extension generated from the mime type if: | 1105 // Append extension generated from the mime type if: |
| 1099 // 1. New extension is not ".txt" | 1106 // 1. New extension is not ".txt" |
| 1100 // 2. New extension is not the same as the already existing extension. | 1107 // 2. New extension is not the same as the already existing extension. |
| 1101 // 3. New extension is not executable. This action mitigates the case when | 1108 // 3. New extension is not executable. This action mitigates the case when |
| 1102 // an execuatable is hidden in a benign file extension; | 1109 // an executable is hidden in a benign file extension; |
| 1103 // E.g. my-cat.jpg becomes my-cat.jpg.js if content type is | 1110 // E.g. my-cat.jpg becomes my-cat.jpg.js if content type is |
| 1104 // application/x-javascript. | 1111 // application/x-javascript. |
| 1105 std::wstring append_extension; | 1112 FilePath::StringType append_extension; |
| 1106 if (net::GetPreferredExtensionForMimeType(mime_type, &append_extension)) { | 1113 if (net::GetPreferredExtensionForMimeType(mime_type, &append_extension)) { |
| 1107 if (append_extension != L".txt" && append_extension != extension && | 1114 if (append_extension != FILE_PATH_LITERAL(".txt") && |
| 1115 append_extension != extension && |
| 1108 !IsExecutable(append_extension)) | 1116 !IsExecutable(append_extension)) |
| 1109 extension += append_extension; | 1117 extension += append_extension; |
| 1110 } | 1118 } |
| 1111 } | 1119 } |
| 1112 | 1120 |
| 1113 generated_extension->swap(extension); | 1121 generated_extension->swap(extension); |
| 1114 } | 1122 } |
| 1115 | 1123 |
| 1116 void DownloadManager::GenerateFilename(DownloadCreateInfo* info, | 1124 void DownloadManager::GenerateFilename(DownloadCreateInfo* info, |
| 1117 std::wstring* generated_name) { | 1125 FilePath* generated_name) { |
| 1118 std::wstring file_name = | 1126 *generated_name = FilePath::FromWStringHack( |
| 1119 net::GetSuggestedFilename(GURL(info->url), | 1127 net::GetSuggestedFilename(GURL(info->url), |
| 1120 info->content_disposition, | 1128 info->content_disposition, |
| 1121 L"download"); | 1129 L"download")); |
| 1122 DCHECK(!file_name.empty()); | 1130 DCHECK(!generated_name->empty()); |
| 1123 | 1131 |
| 1124 GenerateSafeFilename(info->mime_type, &file_name); | 1132 GenerateSafeFilename(info->mime_type, generated_name); |
| 1125 generated_name->assign(file_name); | |
| 1126 } | 1133 } |
| 1127 | 1134 |
| 1128 void DownloadManager::AddObserver(Observer* observer) { | 1135 void DownloadManager::AddObserver(Observer* observer) { |
| 1129 observers_.AddObserver(observer); | 1136 observers_.AddObserver(observer); |
| 1130 observer->ModelChanged(); | 1137 observer->ModelChanged(); |
| 1131 } | 1138 } |
| 1132 | 1139 |
| 1133 void DownloadManager::RemoveObserver(Observer* observer) { | 1140 void DownloadManager::RemoveObserver(Observer* observer) { |
| 1134 observers_.RemoveObserver(observer); | 1141 observers_.RemoveObserver(observer); |
| 1135 } | 1142 } |
| 1136 | 1143 |
| 1137 // Post Windows Shell operations to the Download thread, to avoid blocking the | 1144 // Post Windows Shell operations to the Download thread, to avoid blocking the |
| 1138 // user interface. | 1145 // user interface. |
| 1139 void DownloadManager::ShowDownloadInShell(const DownloadItem* download) { | 1146 void DownloadManager::ShowDownloadInShell(const DownloadItem* download) { |
| 1140 DCHECK(file_manager_); | 1147 DCHECK(file_manager_); |
| 1141 file_loop_->PostTask(FROM_HERE, | 1148 file_loop_->PostTask(FROM_HERE, |
| 1142 NewRunnableMethod(file_manager_, | 1149 NewRunnableMethod(file_manager_, |
| 1143 &DownloadFileManager::OnShowDownloadInShell, | 1150 &DownloadFileManager::OnShowDownloadInShell, |
| 1144 download->full_path())); | 1151 FilePath(download->full_path()))); |
| 1145 } | 1152 } |
| 1146 | 1153 |
| 1147 void DownloadManager::OpenDownloadInShell(const DownloadItem* download, | 1154 void DownloadManager::OpenDownloadInShell(const DownloadItem* download, |
| 1148 HWND parent_window) { | 1155 HWND parent_window) { |
| 1149 DCHECK(file_manager_); | 1156 DCHECK(file_manager_); |
| 1150 file_loop_->PostTask(FROM_HERE, | 1157 file_loop_->PostTask(FROM_HERE, |
| 1151 NewRunnableMethod(file_manager_, | 1158 NewRunnableMethod(file_manager_, |
| 1152 &DownloadFileManager::OnOpenDownloadInShell, | 1159 &DownloadFileManager::OnOpenDownloadInShell, |
| 1153 download->full_path(), download->url(), parent_window)); | 1160 download->full_path(), download->url(), parent_window)); |
| 1154 } | 1161 } |
| 1155 | 1162 |
| 1156 void DownloadManager::OpenFilesOfExtension(const std::wstring& extension, | 1163 void DownloadManager::OpenFilesOfExtension( |
| 1157 bool open) { | 1164 const FilePath::StringType& extension, bool open) { |
| 1158 if (open && !IsExecutable(extension)) | 1165 if (open && !IsExecutable(extension)) |
| 1159 auto_open_.insert(extension); | 1166 auto_open_.insert(extension); |
| 1160 else | 1167 else |
| 1161 auto_open_.erase(extension); | 1168 auto_open_.erase(extension); |
| 1162 SaveAutoOpens(); | 1169 SaveAutoOpens(); |
| 1163 } | 1170 } |
| 1164 | 1171 |
| 1165 bool DownloadManager::ShouldOpenFileExtension(const std::wstring& extension) { | 1172 bool DownloadManager::ShouldOpenFileExtension( |
| 1173 const FilePath::StringType& extension) { |
| 1166 if (!IsExecutable(extension) && | 1174 if (!IsExecutable(extension) && |
| 1167 auto_open_.find(extension) != auto_open_.end()) | 1175 auto_open_.find(extension) != auto_open_.end()) |
| 1168 return true; | 1176 return true; |
| 1169 return false; | 1177 return false; |
| 1170 } | 1178 } |
| 1171 | 1179 |
| 1172 static const char* kExecutableWhiteList[] = { | 1180 static const char* kExecutableWhiteList[] = { |
| 1173 // JavaScript is just as powerful as EXE. | 1181 // JavaScript is just as powerful as EXE. |
| 1174 "text/javascript", | 1182 "text/javascript", |
| 1175 "text/javascript;version=*", | 1183 "text/javascript;version=*", |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1191 return true; | 1199 return true; |
| 1192 } | 1200 } |
| 1193 for (int i=0; i < arraysize(kExecutableBlackList); ++i) { | 1201 for (int i=0; i < arraysize(kExecutableBlackList); ++i) { |
| 1194 if (net::MatchesMimeType(kExecutableBlackList[i], mime_type)) | 1202 if (net::MatchesMimeType(kExecutableBlackList[i], mime_type)) |
| 1195 return false; | 1203 return false; |
| 1196 } | 1204 } |
| 1197 // We consider only other application types to be executable. | 1205 // We consider only other application types to be executable. |
| 1198 return net::MatchesMimeType("application/*", mime_type); | 1206 return net::MatchesMimeType("application/*", mime_type); |
| 1199 } | 1207 } |
| 1200 | 1208 |
| 1201 bool DownloadManager::IsExecutable(const std::wstring& extension) { | 1209 bool DownloadManager::IsExecutable(const FilePath::StringType& extension) { |
| 1202 return exe_types_.find(extension) != exe_types_.end(); | 1210 return exe_types_.find(extension) != exe_types_.end(); |
| 1203 } | 1211 } |
| 1204 | 1212 |
| 1205 void DownloadManager::ResetAutoOpenFiles() { | 1213 void DownloadManager::ResetAutoOpenFiles() { |
| 1206 auto_open_.clear(); | 1214 auto_open_.clear(); |
| 1207 SaveAutoOpens(); | 1215 SaveAutoOpens(); |
| 1208 } | 1216 } |
| 1209 | 1217 |
| 1210 bool DownloadManager::HasAutoOpenFileTypesRegistered() const { | 1218 bool DownloadManager::HasAutoOpenFileTypesRegistered() const { |
| 1211 return !auto_open_.empty(); | 1219 return !auto_open_.empty(); |
| 1212 } | 1220 } |
| 1213 | 1221 |
| 1214 void DownloadManager::SaveAutoOpens() { | 1222 void DownloadManager::SaveAutoOpens() { |
| 1215 PrefService* prefs = profile_->GetPrefs(); | 1223 PrefService* prefs = profile_->GetPrefs(); |
| 1216 if (prefs) { | 1224 if (prefs) { |
| 1217 std::wstring extensions; | 1225 FilePath::StringType extensions; |
| 1218 for (std::set<std::wstring>::iterator it = auto_open_.begin(); | 1226 for (std::set<FilePath::StringType>::iterator it = auto_open_.begin(); |
| 1219 it != auto_open_.end(); ++it) { | 1227 it != auto_open_.end(); ++it) { |
| 1220 extensions += *it + L":"; | 1228 extensions += *it + FILE_PATH_LITERAL(":"); |
| 1221 } | 1229 } |
| 1222 if (!extensions.empty()) | 1230 if (!extensions.empty()) |
| 1223 extensions.erase(extensions.size() - 1); | 1231 extensions.erase(extensions.size() - 1); |
| 1224 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions); | 1232 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions); |
| 1225 } | 1233 } |
| 1226 } | 1234 } |
| 1227 | 1235 |
| 1228 void DownloadManager::FileSelected(const std::wstring& path, void* params) { | 1236 void DownloadManager::FileSelected(const std::wstring& path_string, |
| 1237 void* params) { |
| 1238 FilePath path = FilePath::FromWStringHack(path_string); |
| 1229 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); | 1239 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); |
| 1230 if (info->save_as) | 1240 if (info->save_as) |
| 1231 last_download_path_ = file_util::GetDirectoryFromPath(path); | 1241 last_download_path_ = path.DirName(); |
| 1232 ContinueStartDownload(info, path); | 1242 ContinueStartDownload(info, path); |
| 1233 } | 1243 } |
| 1234 | 1244 |
| 1235 void DownloadManager::FileSelectionCanceled(void* params) { | 1245 void DownloadManager::FileSelectionCanceled(void* params) { |
| 1236 // The user didn't pick a place to save the file, so need to cancel the | 1246 // The user didn't pick a place to save the file, so need to cancel the |
| 1237 // download that's already in progress to the temporary location. | 1247 // download that's already in progress to the temporary location. |
| 1238 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); | 1248 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); |
| 1239 file_loop_->PostTask(FROM_HERE, | 1249 file_loop_->PostTask(FROM_HERE, |
| 1240 NewRunnableMethod(file_manager_, &DownloadFileManager::CancelDownload, | 1250 NewRunnableMethod(file_manager_, &DownloadFileManager::CancelDownload, |
| 1241 info->download_id)); | 1251 info->download_id)); |
| 1242 } | 1252 } |
| 1243 | 1253 |
| 1244 void DownloadManager::DeleteDownload(const std::wstring& path) { | 1254 void DownloadManager::DeleteDownload(const FilePath& path) { |
| 1245 file_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 1255 file_loop_->PostTask(FROM_HERE, NewRunnableFunction( |
| 1246 file_manager_, &DownloadFileManager::DeleteFile, path)); | 1256 &DownloadFileManager::DeleteFile, FilePath(path))); |
| 1247 } | 1257 } |
| 1248 | 1258 |
| 1249 | 1259 |
| 1250 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { | 1260 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { |
| 1251 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); | 1261 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); |
| 1252 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); | 1262 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); |
| 1253 download->UpdateObservers(); | 1263 download->UpdateObservers(); |
| 1254 | 1264 |
| 1255 // If the download is not complete, nothing to do. The required | 1265 // If the download is not complete, nothing to do. The required |
| 1256 // post-processing will be performed when it does complete. | 1266 // post-processing will be performed when it does complete. |
| 1257 if (download->state() != DownloadItem::COMPLETE) | 1267 if (download->state() != DownloadItem::COMPLETE) |
| 1258 return; | 1268 return; |
| 1259 | 1269 |
| 1260 file_loop_->PostTask(FROM_HERE, | 1270 file_loop_->PostTask(FROM_HERE, |
| 1261 NewRunnableMethod(this, | 1271 NewRunnableMethod(this, |
| 1262 &DownloadManager::ProceedWithFinishedDangerousDownload, | 1272 &DownloadManager::ProceedWithFinishedDangerousDownload, |
| 1263 download->db_handle(), download->full_path(), | 1273 download->db_handle(), download->full_path(), |
| 1264 download->original_name())); | 1274 download->original_name())); |
| 1265 } | 1275 } |
| 1266 | 1276 |
| 1267 void DownloadManager::GenerateSafeFilename(const std::string& mime_type, | 1277 void DownloadManager::GenerateSafeFilename(const std::string& mime_type, |
| 1268 std::wstring* file_name) { | 1278 FilePath* file_name) { |
| 1269 // Make sure we get the right file extension. | 1279 // Make sure we get the right file extension |
| 1270 std::wstring extension; | 1280 FilePath::StringType extension; |
| 1271 GenerateExtension(*file_name, mime_type, &extension); | 1281 GenerateExtension(*file_name, mime_type, &extension); |
| 1272 file_util::ReplaceExtension(file_name, extension); | 1282 file_util::ReplaceExtension(file_name, extension); |
| 1273 | 1283 |
| 1274 // Prepend "_" to the file name if it's a reserved name | 1284 // Prepend "_" to the file name if it's a reserved name |
| 1275 std::wstring leaf_name = file_util::GetFilenameFromPath(*file_name); | 1285 FilePath::StringType leaf_name = file_name->BaseName().value(); |
| 1276 DCHECK(!leaf_name.empty()); | 1286 DCHECK(!leaf_name.empty()); |
| 1277 if (win_util::IsReservedName(leaf_name)) { | 1287 if (win_util::IsReservedName(leaf_name)) { |
| 1278 file_util::UpOneDirectoryOrEmpty(file_name); | 1288 leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name; |
| 1279 if (file_name->empty()) { | 1289 *file_name = file_name->DirName(); |
| 1280 file_name->assign(std::wstring(L"_") + leaf_name); | 1290 if (file_name->value() == FilePath::kCurrentDirectory) { |
| 1291 *file_name = FilePath(leaf_name); |
| 1281 } else { | 1292 } else { |
| 1282 file_util::AppendToPath(file_name, std::wstring(L"_") + leaf_name); | 1293 *file_name = file_name->Append(leaf_name); |
| 1283 } | 1294 } |
| 1284 } | 1295 } |
| 1285 } | 1296 } |
| 1286 | 1297 |
| 1287 // Operations posted to us from the history service ---------------------------- | 1298 // Operations posted to us from the history service ---------------------------- |
| 1288 | 1299 |
| 1289 // The history service has retrieved all download entries. 'entries' contains | 1300 // The history service has retrieved all download entries. 'entries' contains |
| 1290 // 'DownloadCreateInfo's in sorted order (by ascending start_time). | 1301 // 'DownloadCreateInfo's in sorted order (by ascending start_time). |
| 1291 void DownloadManager::OnQueryDownloadEntriesComplete( | 1302 void DownloadManager::OnQueryDownloadEntriesComplete( |
| 1292 std::vector<DownloadCreateInfo>* entries) { | 1303 std::vector<DownloadCreateInfo>* entries) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 DownloadMap::iterator dit = downloads_.find(*it); | 1378 DownloadMap::iterator dit = downloads_.find(*it); |
| 1368 if (dit != downloads_.end()) | 1379 if (dit != downloads_.end()) |
| 1369 searched_downloads.push_back(dit->second); | 1380 searched_downloads.push_back(dit->second); |
| 1370 } | 1381 } |
| 1371 | 1382 |
| 1372 requestor->SetDownloads(searched_downloads); | 1383 requestor->SetDownloads(searched_downloads); |
| 1373 } | 1384 } |
| 1374 | 1385 |
| 1375 // Clears the last download path, used to initialize "save as" dialogs. | 1386 // Clears the last download path, used to initialize "save as" dialogs. |
| 1376 void DownloadManager::ClearLastDownloadPath() { | 1387 void DownloadManager::ClearLastDownloadPath() { |
| 1377 last_download_path_.clear(); | 1388 last_download_path_ = FilePath(); |
| 1378 } | 1389 } |
| OLD | NEW |