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 |