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