Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(667)

Side by Side Diff: chrome/browser/download/download_manager.cc

Issue 6043: Added dangerous download prompting. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/registry.h" 13 #include "base/registry.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/task.h" 15 #include "base/task.h"
16 #include "base/thread.h" 16 #include "base/thread.h"
17 #include "base/timer.h" 17 #include "base/timer.h"
18 #include "base/rand_util.h"
18 #include "base/win_util.h" 19 #include "base/win_util.h"
19 #include "chrome/browser/browser_list.h" 20 #include "chrome/browser/browser_list.h"
20 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/download/download_file.h" 22 #include "chrome/browser/download/download_file.h"
22 #include "chrome/browser/download/download_util.h" 23 #include "chrome/browser/download/download_util.h"
23 #include "chrome/browser/profile.h" 24 #include "chrome/browser/profile.h"
24 #include "chrome/browser/render_process_host.h" 25 #include "chrome/browser/render_process_host.h"
25 #include "chrome/browser/render_view_host.h" 26 #include "chrome/browser/render_view_host.h"
26 #include "chrome/browser/resource_dispatcher_host.h" 27 #include "chrome/browser/resource_dispatcher_host.h"
27 #include "chrome/browser/tab_util.h" 28 #include "chrome/browser/tab_util.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 } 91 }
91 return (download_path == desktop_dir); 92 return (download_path == desktop_dir);
92 } 93 }
93 94
94 // DownloadItem implementation ------------------------------------------------- 95 // DownloadItem implementation -------------------------------------------------
95 96
96 // Constructor for reading from the history service. 97 // Constructor for reading from the history service.
97 DownloadItem::DownloadItem(const DownloadCreateInfo& info) 98 DownloadItem::DownloadItem(const DownloadCreateInfo& info)
98 : id_(-1), 99 : id_(-1),
99 full_path_(info.path), 100 full_path_(info.path),
101 original_name_(info.original_name),
100 url_(info.url), 102 url_(info.url),
101 total_bytes_(info.total_bytes), 103 total_bytes_(info.total_bytes),
102 received_bytes_(info.received_bytes), 104 received_bytes_(info.received_bytes),
103 start_tick_(0), 105 start_tick_(0),
104 state_(static_cast<DownloadState>(info.state)), 106 state_(static_cast<DownloadState>(info.state)),
105 start_time_(info.start_time), 107 start_time_(info.start_time),
106 db_handle_(info.db_handle), 108 db_handle_(info.db_handle),
107 manager_(NULL), 109 manager_(NULL),
110 safety_state_(SAFE),
108 is_paused_(false), 111 is_paused_(false),
109 open_when_complete_(false), 112 open_when_complete_(false),
110 render_process_id_(-1), 113 render_process_id_(-1),
111 request_id_(-1) { 114 request_id_(-1) {
112 if (state_ == IN_PROGRESS) 115 if (state_ == IN_PROGRESS)
113 state_ = CANCELLED; 116 state_ = CANCELLED;
114 Init(false /* don't start progress timer */); 117 Init(false /* don't start progress timer */);
115 } 118 }
116 119
117 // Constructor for DownloadItem created via user action in the main thread. 120 // Constructor for DownloadItem created via user action in the main thread.
118 DownloadItem::DownloadItem(int32 download_id, 121 DownloadItem::DownloadItem(int32 download_id,
119 const std::wstring& path, 122 const std::wstring& path,
120 const std::wstring& url, 123 const std::wstring& url,
124 const std::wstring& original_name,
121 const Time start_time, 125 const Time start_time,
122 int64 download_size, 126 int64 download_size,
123 int render_process_id, 127 int render_process_id,
124 int request_id) 128 int request_id,
129 bool is_dangerous)
125 : id_(download_id), 130 : id_(download_id),
126 full_path_(path), 131 full_path_(path),
127 url_(url), 132 url_(url),
133 original_name_(original_name),
128 total_bytes_(download_size), 134 total_bytes_(download_size),
129 received_bytes_(0), 135 received_bytes_(0),
130 start_tick_(GetTickCount()), 136 start_tick_(GetTickCount()),
131 state_(IN_PROGRESS), 137 state_(IN_PROGRESS),
132 start_time_(start_time), 138 start_time_(start_time),
133 db_handle_(kUninitializedHandle), 139 db_handle_(kUninitializedHandle),
134 manager_(NULL), 140 manager_(NULL),
141 safety_state_(is_dangerous ? DANGEROUS : SAFE),
135 is_paused_(false), 142 is_paused_(false),
136 open_when_complete_(false), 143 open_when_complete_(false),
137 render_process_id_(render_process_id), 144 render_process_id_(render_process_id),
138 request_id_(request_id) { 145 request_id_(request_id) {
139 Init(true /* start progress timer */); 146 Init(true /* start progress timer */);
140 } 147 }
141 148
142 void DownloadItem::Init(bool start_timer) { 149 void DownloadItem::Init(bool start_timer) {
143 file_name_ = file_util::GetFilenameFromPath(full_path_); 150 file_name_ = file_util::GetFilenameFromPath(full_path_);
144 if (start_timer) 151 if (start_timer)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 state_ = CANCELLED; 198 state_ = CANCELLED;
192 UpdateObservers(); 199 UpdateObservers();
193 StopProgressTimer(); 200 StopProgressTimer();
194 if (update_history) 201 if (update_history)
195 manager_->DownloadCancelled(id_); 202 manager_->DownloadCancelled(id_);
196 } 203 }
197 204
198 void DownloadItem::Finished(int64 size) { 205 void DownloadItem::Finished(int64 size) {
199 state_ = COMPLETE; 206 state_ = COMPLETE;
200 UpdateSize(size); 207 UpdateSize(size);
201 UpdateObservers();
202 StopProgressTimer(); 208 StopProgressTimer();
203 } 209 }
204 210
205 void DownloadItem::Remove() { 211 void DownloadItem::Remove(bool delete_on_disk) {
206 Cancel(true); 212 Cancel(true);
207 state_ = REMOVING; 213 state_ = REMOVING;
214 if (delete_on_disk)
215 manager_->DeleteDownload(full_path_);
208 manager_->RemoveDownload(db_handle_); 216 manager_->RemoveDownload(db_handle_);
217 // We are now deleted.
209 } 218 }
210 219
211 void DownloadItem::StartProgressTimer() { 220 void DownloadItem::StartProgressTimer() {
212 update_timer_.Start(TimeDelta::FromMilliseconds(kUpdateTimeMs), this, 221 update_timer_.Start(TimeDelta::FromMilliseconds(kUpdateTimeMs), this,
213 &DownloadItem::UpdateObservers); 222 &DownloadItem::UpdateObservers);
214 } 223 }
215 224
216 void DownloadItem::StopProgressTimer() { 225 void DownloadItem::StopProgressTimer() {
217 update_timer_.Stop(); 226 update_timer_.Stop();
218 } 227 }
(...skipping 29 matching lines...) Expand all
248 file_name_ = file_util::GetFilenameFromPath(full_path_); 257 file_name_ = file_util::GetFilenameFromPath(full_path_);
249 } 258 }
250 259
251 void DownloadItem::TogglePause() { 260 void DownloadItem::TogglePause() {
252 DCHECK(state_ == IN_PROGRESS); 261 DCHECK(state_ == IN_PROGRESS);
253 manager_->PauseDownload(id_, !is_paused_); 262 manager_->PauseDownload(id_, !is_paused_);
254 is_paused_ = !is_paused_; 263 is_paused_ = !is_paused_;
255 UpdateObservers(); 264 UpdateObservers();
256 } 265 }
257 266
267 std::wstring DownloadItem::GetFileName() const {
268 if (safety_state_ == DownloadItem::SAFE)
269 return file_name_;
270 return original_name_;
271 }
272
258 // DownloadManager implementation ---------------------------------------------- 273 // DownloadManager implementation ----------------------------------------------
259 274
260 // static 275 // static
261 void DownloadManager::RegisterUserPrefs(PrefService* prefs) { 276 void DownloadManager::RegisterUserPrefs(PrefService* prefs) {
262 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false); 277 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false);
263 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, L""); 278 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, L"");
264 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); 279 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false);
265 280
266 // The default download path is userprofile\download. 281 // The default download path is userprofile\download.
267 std::wstring default_download_path; 282 std::wstring default_download_path;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 321
307 // Stop receiving download updates 322 // Stop receiving download updates
308 file_manager_->RemoveDownloadManager(this); 323 file_manager_->RemoveDownloadManager(this);
309 324
310 // Stop making history service requests 325 // Stop making history service requests
311 cancelable_consumer_.CancelAllRequests(); 326 cancelable_consumer_.CancelAllRequests();
312 327
313 // 'in_progress_' may contain DownloadItems that have not finished the start 328 // 'in_progress_' may contain DownloadItems that have not finished the start
314 // complete (from the history service) and thus aren't in downloads_. 329 // complete (from the history service) and thus aren't in downloads_.
315 DownloadMap::iterator it = in_progress_.begin(); 330 DownloadMap::iterator it = in_progress_.begin();
331 std::set<DownloadItem*> to_remove;
316 for (; it != in_progress_.end(); ++it) { 332 for (; it != in_progress_.end(); ++it) {
317 DownloadItem* download = it->second; 333 DownloadItem* download = it->second;
318 if (download->state() == DownloadItem::IN_PROGRESS) { 334 if (download->safety_state() == DownloadItem::DANGEROUS) {
319 download->Cancel(false); 335 // Forget about any download that the user did not approve.
320 UpdateHistoryForDownload(download); 336 // Note that we cannot call download->Remove() this would invalidate our
337 // iterator.
338 to_remove.insert(download);
339 continue;
321 } 340 }
341 DCHECK_EQ(DownloadItem::IN_PROGRESS, download->state());
342 download->Cancel(false);
343 UpdateHistoryForDownload(download);
322 if (download->db_handle() == kUninitializedHandle) { 344 if (download->db_handle() == kUninitializedHandle) {
323 // An invalid handle means that 'download' does not yet exist in 345 // An invalid handle means that 'download' does not yet exist in
324 // 'downloads_', so we have to delete it here. 346 // 'downloads_', so we have to delete it here.
325 delete download; 347 delete download;
326 } 348 }
327 } 349 }
328 350
351 // 'dangerous_finished_' contains all complete downloads that have not been
352 // approved. They should be removed.
353 it = dangerous_finished_.begin();
354 for (; it != dangerous_finished_.end(); ++it)
355 to_remove.insert(it->second);
356
357 // Remove the dangerous download that are not approved.
358 for (std::set<DownloadItem*>::const_iterator rm_it = to_remove.begin();
359 rm_it != to_remove.end(); ++rm_it) {
360 DownloadItem* download = *rm_it;
361 download->Remove(true);
362 // Same as above, delete the download if it is not in 'downloads_'.
363 if (download->db_handle() == kUninitializedHandle)
364 delete download;
365 }
366 to_remove.clear();
367
329 in_progress_.clear(); 368 in_progress_.clear();
369 dangerous_finished_.clear();
330 STLDeleteValues(&downloads_); 370 STLDeleteValues(&downloads_);
331 371
332 file_manager_ = NULL; 372 file_manager_ = NULL;
333 373
334 // Save our file extensions to auto open. 374 // Save our file extensions to auto open.
335 SaveAutoOpens(); 375 SaveAutoOpens();
336 376
337 // Make sure the save as dialog doesn't notify us back if we're gone before 377 // Make sure the save as dialog doesn't notify us back if we're gone before
338 // it returns. 378 // it returns.
339 if (select_file_dialog_.get()) 379 if (select_file_dialog_.get())
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 NewRunnableMethod(this, 519 NewRunnableMethod(this,
480 &DownloadManager::CheckIfSuggestedPathExists, 520 &DownloadManager::CheckIfSuggestedPathExists,
481 info)); 521 info));
482 } 522 }
483 523
484 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { 524 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
485 DCHECK(info); 525 DCHECK(info);
486 526
487 // Check writability of the suggested path. If we can't write to it, default 527 // Check writability of the suggested path. If we can't write to it, default
488 // to the user's "My Documents" directory. We'll prompt them in this case. 528 // to the user's "My Documents" directory. We'll prompt them in this case.
489 std::wstring path = file_util::GetDirectoryFromPath(info->suggested_path); 529 std::wstring dir = file_util::GetDirectoryFromPath(info->suggested_path);
490 if (!file_util::PathIsWritable(path)) { 530 const std::wstring filename =
531 file_util::GetFilenameFromPath(info->suggested_path);
532 if (!file_util::PathIsWritable(dir)) {
491 info->save_as = true; 533 info->save_as = true;
492 const std::wstring filename =
493 file_util::GetFilenameFromPath(info->suggested_path);
494 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); 534 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path);
495 file_util::AppendToPath(&info->suggested_path, filename); 535 file_util::AppendToPath(&info->suggested_path, filename);
496 } 536 }
497 537
498 info->suggested_path_exists = !UniquifyPath(&info->suggested_path); 538 info->suggested_path_exists = !UniquifyPath(&info->suggested_path);
499 539
540 // If the download is deemmed dangerous, we'll use a temporary name for it.
541 if (!info->save_as && IsDangerous(filename)) {
542 info->original_name = file_util::GetFilenameFromPath(info->suggested_path);
543 // Create a temporary file to hold the file until the user approves its
544 // download.
545 std::wstring file_name;
546 std::wstring path;
547 while (path.empty()) {
548 SStringPrintf(&file_name, L"dangerous_download_%d.download",
Mark Larson 2008/10/10 20:48:17 Let's not use DANGER! DANGER! for these files. The
549 base::RandInt(0, 100000));
550 path = dir;
551 file_util::AppendToPath(&path, file_name);
552 if (file_util::PathExists(path))
553 path.clear();
554 }
555 info->suggested_path = path;
556 info->is_dangerous = true;
557 }
558
500 // Now we return to the UI thread. 559 // Now we return to the UI thread.
501 ui_loop_->PostTask(FROM_HERE, 560 ui_loop_->PostTask(FROM_HERE,
502 NewRunnableMethod(this, 561 NewRunnableMethod(this,
503 &DownloadManager::OnPathExistenceAvailable, 562 &DownloadManager::OnPathExistenceAvailable,
504 info)); 563 info));
505 } 564 }
506 565
507 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 566 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
508 DCHECK(MessageLoop::current() == ui_loop_); 567 DCHECK(MessageLoop::current() == ui_loop_);
509 DCHECK(info); 568 DCHECK(info);
(...skipping 20 matching lines...) Expand all
530 const std::wstring& target_path) { 589 const std::wstring& target_path) {
531 scoped_ptr<DownloadCreateInfo> infop(info); 590 scoped_ptr<DownloadCreateInfo> infop(info);
532 info->path = target_path; 591 info->path = target_path;
533 592
534 DownloadItem* download = NULL; 593 DownloadItem* download = NULL;
535 DownloadMap::iterator it = in_progress_.find(info->download_id); 594 DownloadMap::iterator it = in_progress_.find(info->download_id);
536 if (it == in_progress_.end()) { 595 if (it == in_progress_.end()) {
537 download = new DownloadItem(info->download_id, 596 download = new DownloadItem(info->download_id,
538 info->path, 597 info->path,
539 info->url, 598 info->url,
599 info->original_name,
540 info->start_time, 600 info->start_time,
541 info->total_bytes, 601 info->total_bytes,
542 info->render_process_id, 602 info->render_process_id,
543 info->request_id); 603 info->request_id,
604 info->is_dangerous);
544 download->set_manager(this); 605 download->set_manager(this);
545 in_progress_[info->download_id] = download; 606 in_progress_[info->download_id] = download;
546 } else { 607 } else {
547 NOTREACHED(); // Should not exist! 608 NOTREACHED(); // Should not exist!
548 return; 609 return;
549 } 610 }
550 611
551 // If the download already completed by the time we reached this point, then 612 // If the download already completed by the time we reached this point, then
552 // notify observers that it did. 613 // notify observers that it did.
553 PendingFinishedMap::iterator pending_it = 614 PendingFinishedMap::iterator pending_it =
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 DownloadMap::iterator it = in_progress_.find(download_id); 682 DownloadMap::iterator it = in_progress_.find(download_id);
622 if (it != in_progress_.end()) { 683 if (it != in_progress_.end()) {
623 DownloadItem* download = it->second; 684 DownloadItem* download = it->second;
624 download->Update(size); 685 download->Update(size);
625 UpdateHistoryForDownload(download); 686 UpdateHistoryForDownload(download);
626 } 687 }
627 } 688 }
628 689
629 void DownloadManager::DownloadFinished(int32 download_id, int64 size) { 690 void DownloadManager::DownloadFinished(int32 download_id, int64 size) {
630 DownloadMap::iterator it = in_progress_.find(download_id); 691 DownloadMap::iterator it = in_progress_.find(download_id);
631 if (it != in_progress_.end()) { 692 if (it == in_progress_.end()) {
632 // Remove the id from the list of pending ids.
633 PendingFinishedMap::iterator erase_it =
634 pending_finished_downloads_.find(download_id);
635 if (erase_it != pending_finished_downloads_.end())
636 pending_finished_downloads_.erase(erase_it);
637
638 DownloadItem* download = it->second;
639 download->Finished(size);
640
641 // Open the download if the user or user prefs indicate it should be.
642 const std::wstring extension =
643 file_util::GetFileExtensionFromPath(download->full_path());
644 if (download->open_when_complete() || ShouldOpenFileExtension(extension))
645 OpenDownloadInShell(download, NULL);
646
647 // Clean up will happen when the history system create callback runs if we
648 // don't have a valid db_handle yet.
649 if (download->db_handle() != kUninitializedHandle) {
650 in_progress_.erase(it);
651 NotifyAboutDownloadStop();
652 UpdateHistoryForDownload(download);
653 }
654 } else {
655 // The download is done, but the user hasn't selected a final location for 693 // The download is done, but the user hasn't selected a final location for
656 // it yet (the Save As dialog box is probably still showing), so just keep 694 // it yet (the Save As dialog box is probably still showing), so just keep
657 // track of the fact that this download id is complete, when the 695 // track of the fact that this download id is complete, when the
658 // DownloadItem is constructed later we'll notify its completion then. 696 // DownloadItem is constructed later we'll notify its completion then.
659 PendingFinishedMap::iterator erase_it = 697 PendingFinishedMap::iterator erase_it =
660 pending_finished_downloads_.find(download_id); 698 pending_finished_downloads_.find(download_id);
661 DCHECK(erase_it == pending_finished_downloads_.end()); 699 DCHECK(erase_it == pending_finished_downloads_.end());
662 pending_finished_downloads_[download_id] = size; 700 pending_finished_downloads_[download_id] = size;
701 return;
663 } 702 }
703
704 // Remove the id from the list of pending ids.
705 PendingFinishedMap::iterator erase_it =
706 pending_finished_downloads_.find(download_id);
707 if (erase_it != pending_finished_downloads_.end())
708 pending_finished_downloads_.erase(erase_it);
709
710 DownloadItem* download = it->second;
711 download->Finished(size);
712
713 // Clean up will happen when the history system create callback runs if we
714 // don't have a valid db_handle yet.
715 if (download->db_handle() != kUninitializedHandle) {
716 in_progress_.erase(it);
717 NotifyAboutDownloadStop();
718 UpdateHistoryForDownload(download);
719 }
720
721 // If this a dangerous download not yet validated by the user, don't do
722 // anything. When the user notifies us, it will trigger a call to
723 // ProceedWithFinishedDangerousDownload.
724 if (download->safety_state() == DownloadItem::DANGEROUS) {
725 dangerous_finished_[download_id] = download;
726 return;
727 }
728
729 if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
730 // We first need to rename the donwloaded file from its temporary name to
731 // its final name before we can continue.
732 file_loop_->PostTask(FROM_HERE,
733 NewRunnableMethod(
734 this, &DownloadManager::ProceedWithFinishedDangerousDownload,
735 download->db_handle(),
736 download->full_path(), download->original_name()));
737 return;
738 }
739 ContinueDownloadFinished(download);
740 }
741
742 void DownloadManager::ContinueDownloadFinished(DownloadItem* download) {
743 // If this was a dangerous download, it has now been approved and must be
744 // removed from dangerous_finished_ so it does not get deleted on shutdown.
745 DownloadMap::iterator it = dangerous_finished_.find(download->id());
746 if (it != dangerous_finished_.end())
747 dangerous_finished_.erase(it);
748
749 // Notify our observers that we are complete (the call to Finished() set the
750 // state to complete but did not notify).
751 download->UpdateObservers();
752
753 // Open the download if the user or user prefs indicate it should be.
754 const std::wstring extension =
755 file_util::GetFileExtensionFromPath(download->full_path());
756 if (download->open_when_complete() || ShouldOpenFileExtension(extension))
757 OpenDownloadInShell(download, NULL);
758 }
759
760 // Called on the file thread. Renames the downloaded file to its original name.
761 void DownloadManager::ProceedWithFinishedDangerousDownload(
762 int64 download_handle,
763 const std::wstring& path,
764 const std::wstring& original_name) {
765 bool success = false;
766 std::wstring new_path = path;
767 if (file_util::PathExists(path)) {
768 new_path = file_util::GetDirectoryFromPath(new_path);
769 file_util::AppendToPath(&new_path, original_name);
770 success = file_util::Move(path, new_path);
771 } else {
772 NOTREACHED();
773 }
774
775 ui_loop_->PostTask(FROM_HERE,
776 NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed,
777 download_handle, success, new_path));
778 }
779
780 // Call from the file thread when the finished dangerous download was renamed.
781 void DownloadManager::DangerousDownloadRenamed(int64 download_handle,
782 bool success,
783 const std::wstring& new_path) {
784 DownloadMap::iterator it = downloads_.find(download_handle);
785 if (it == downloads_.end()) {
786 NOTREACHED();
787 return;
788 }
789
790 DownloadItem* download = it->second;
791 // If we failed to rename the file, we'll just keep the name as is.
792 if (success)
793 RenameDownload(download, new_path);
794
795 // Continue the download finished sequence.
796 ContinueDownloadFinished(download);
664 } 797 }
665 798
666 // static 799 // static
667 // We have to tell the ResourceDispatcherHost to cancel the download from this 800 // We have to tell the ResourceDispatcherHost to cancel the download from this
668 // thread, since we can't forward tasks from the file thread to the io thread 801 // thread, since we can't forward tasks from the file thread to the io thread
669 // reliably (crash on shutdown race condition). 802 // reliably (crash on shutdown race condition).
670 void DownloadManager::CancelDownloadRequest(int render_process_id, 803 void DownloadManager::CancelDownloadRequest(int render_process_id,
671 int request_id) { 804 int request_id) {
672 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host(); 805 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host();
673 base::Thread* io_thread = g_browser_process->io_thread(); 806 base::Thread* io_thread = g_browser_process->io_thread();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 } 867 }
735 868
736 // static 869 // static
737 void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh, 870 void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
738 int render_process_id, 871 int render_process_id,
739 int request_id, 872 int request_id,
740 bool pause) { 873 bool pause) {
741 rdh->PauseRequest(render_process_id, request_id, pause); 874 rdh->PauseRequest(render_process_id, request_id, pause);
742 } 875 }
743 876
877 bool DownloadManager::IsDangerous(const std::wstring& file_name) {
878 // TODO(jcampan): Improve me.
879 return IsExecutable(file_util::GetFileExtensionFromPath(file_name));
880 }
881
882 void DownloadManager::RenameDownload(DownloadItem* download,
883 const std::wstring& new_path) {
884 download->Rename(new_path);
885
886 // Update the history.
887
888 // No update necessary if the download was initiated while in incognito mode.
889 if (download->db_handle() <= kUninitializedHandle)
890 return;
891
892 // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
893 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
894 if (hs)
895 hs->UpdateDownloadPath(new_path, download->db_handle());
896 }
897
744 void DownloadManager::RemoveDownload(int64 download_handle) { 898 void DownloadManager::RemoveDownload(int64 download_handle) {
745 DownloadMap::iterator it = downloads_.find(download_handle); 899 DownloadMap::iterator it = downloads_.find(download_handle);
746 if (it == downloads_.end()) 900 if (it == downloads_.end())
747 return; 901 return;
748 902
749 // Make history update. 903 // Make history update.
750 DownloadItem* download = it->second; 904 DownloadItem* download = it->second;
751 RemoveDownloadFromHistory(download); 905 RemoveDownloadFromHistory(download);
752 906
753 // Remove from our tables and delete. 907 // Remove from our tables and delete.
754 downloads_.erase(it); 908 downloads_.erase(it);
909 it = dangerous_finished_.find(download->id());
910 if (it != dangerous_finished_.end())
911 dangerous_finished_.erase(it);
755 delete download; 912 delete download;
756 913
757 // Tell observers to refresh their views. 914 // Tell observers to refresh their views.
758 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); 915 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged());
759 } 916 }
760 917
761 int DownloadManager::RemoveDownloadsBetween(const Time remove_begin, 918 int DownloadManager::RemoveDownloadsBetween(const Time remove_begin,
762 const Time remove_end) { 919 const Time remove_end) {
763 RemoveDownloadsFromHistoryBetween(remove_begin, remove_end); 920 RemoveDownloadsFromHistoryBetween(remove_begin, remove_end);
764 921
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 1164
1008 void DownloadManager::FileSelectionCanceled(void* params) { 1165 void DownloadManager::FileSelectionCanceled(void* params) {
1009 // The user didn't pick a place to save the file, so need to cancel the 1166 // The user didn't pick a place to save the file, so need to cancel the
1010 // download that's already in progress to the temporary location. 1167 // download that's already in progress to the temporary location.
1011 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1168 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1012 file_loop_->PostTask(FROM_HERE, 1169 file_loop_->PostTask(FROM_HERE,
1013 NewRunnableMethod(file_manager_, &DownloadFileManager::CancelDownload, 1170 NewRunnableMethod(file_manager_, &DownloadFileManager::CancelDownload,
1014 info->download_id)); 1171 info->download_id));
1015 } 1172 }
1016 1173
1174 void DownloadManager::DeleteDownload(const std::wstring& path) {
1175 file_loop_->PostTask(FROM_HERE, NewRunnableMethod(
1176 file_manager_, &DownloadFileManager::DeleteFile, path));
1177 }
1178
1179
1180 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
1181 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
1182 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
1183 download->UpdateObservers();
1184
1185 // If the download is not complete, nothing to do. The required
1186 // post-processing will be performed when it does complete.
1187 if (download->state() != DownloadItem::COMPLETE)
1188 return;
1189
1190 file_loop_->PostTask(FROM_HERE,
1191 NewRunnableMethod(this,
1192 &DownloadManager::ProceedWithFinishedDangerousDownload,
1193 download->db_handle(), download->full_path(),
1194 download->original_name()));
1195 }
1196
1017 // Operations posted to us from the history service ---------------------------- 1197 // Operations posted to us from the history service ----------------------------
1018 1198
1019 // The history service has retrieved all download entries. 'entries' contains 1199 // The history service has retrieved all download entries. 'entries' contains
1020 // 'DownloadCreateInfo's in sorted order (by ascending start_time). 1200 // 'DownloadCreateInfo's in sorted order (by ascending start_time).
1021 void DownloadManager::OnQueryDownloadEntriesComplete( 1201 void DownloadManager::OnQueryDownloadEntriesComplete(
1022 std::vector<DownloadCreateInfo>* entries) { 1202 std::vector<DownloadCreateInfo>* entries) {
1023 for (size_t i = 0; i < entries->size(); ++i) { 1203 for (size_t i = 0; i < entries->size(); ++i) {
1024 DownloadItem* download = new DownloadItem(entries->at(i)); 1204 DownloadItem* download = new DownloadItem(entries->at(i));
1025 DCHECK(downloads_.find(download->db_handle()) == downloads_.end()); 1205 DCHECK(downloads_.find(download->db_handle()) == downloads_.end());
1026 downloads_[download->db_handle()] = download; 1206 downloads_[download->db_handle()] = download;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 for (std::vector<int64>::iterator it = results->begin(); 1275 for (std::vector<int64>::iterator it = results->begin();
1096 it != results->end(); ++it) { 1276 it != results->end(); ++it) {
1097 DownloadMap::iterator dit = downloads_.find(*it); 1277 DownloadMap::iterator dit = downloads_.find(*it);
1098 if (dit != downloads_.end()) 1278 if (dit != downloads_.end())
1099 searched_downloads.push_back(dit->second); 1279 searched_downloads.push_back(dit->second);
1100 } 1280 }
1101 1281
1102 requestor->SetDownloads(searched_downloads); 1282 requestor->SetDownloads(searched_downloads);
1103 } 1283 }
1104 1284
OLDNEW
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698