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

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

Issue 14640020: [Resumption 9/11] Handle filename determination for resumed downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 7 years, 7 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/download/download_target_determiner.h" 5 #include "chrome/browser/download/download_target_determiner.h"
6 6
7 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
8 #include "base/rand_util.h" 8 #include "base/rand_util.h"
9 #include "base/stringprintf.h" 9 #include "base/stringprintf.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "chrome/browser/download/chrome_download_manager_delegate.h" 11 #include "chrome/browser/download/chrome_download_manager_delegate.h"
12 #include "chrome/browser/download/download_crx_util.h" 12 #include "chrome/browser/download/download_crx_util.h"
13 #include "chrome/browser/download/download_extensions.h" 13 #include "chrome/browser/download/download_extensions.h"
14 #include "chrome/browser/download/download_prefs.h" 14 #include "chrome/browser/download/download_prefs.h"
15 #include "chrome/browser/download/download_util.h" 15 #include "chrome/browser/download/download_util.h"
16 #include "chrome/browser/extensions/webstore_installer.h" 16 #include "chrome/browser/extensions/webstore_installer.h"
17 #include "chrome/browser/history/history_service.h" 17 #include "chrome/browser/history/history_service.h"
18 #include "chrome/browser/history/history_service_factory.h" 18 #include "chrome/browser/history/history_service_factory.h"
19 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/feature_switch.h" 21 #include "chrome/common/extensions/feature_switch.h"
22 #include "chrome/common/pref_names.h" 22 #include "chrome/common/pref_names.h"
23 #include "content/public/browser/browser_context.h" 23 #include "content/public/browser/browser_context.h"
24 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/download_interrupt_reasons.h"
25 #include "grit/generated_resources.h" 26 #include "grit/generated_resources.h"
26 #include "net/base/net_util.h" 27 #include "net/base/net_util.h"
27 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
28 29
29 #if defined(OS_CHROMEOS) 30 #if defined(OS_CHROMEOS)
30 #include "chrome/browser/chromeos/drive/download_handler.h" 31 #include "chrome/browser/chromeos/drive/download_handler.h"
31 #include "chrome/browser/chromeos/drive/file_system_util.h" 32 #include "chrome/browser/chromeos/drive/file_system_util.h"
32 #endif 33 #endif
33 34
34 using content::BrowserThread; 35 using content::BrowserThread;
(...skipping 16 matching lines...) Expand all
51 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); 52 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
52 } 53 }
53 54
54 } // namespace 55 } // namespace
55 56
56 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { 57 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() {
57 } 58 }
58 59
59 DownloadTargetDeterminer::DownloadTargetDeterminer( 60 DownloadTargetDeterminer::DownloadTargetDeterminer(
60 DownloadItem* download, 61 DownloadItem* download,
62 const base::FilePath& initial_virtual_path,
61 DownloadPrefs* download_prefs, 63 DownloadPrefs* download_prefs,
62 const base::FilePath& last_selected_directory, 64 const base::FilePath& last_selected_directory,
63 DownloadTargetDeterminerDelegate* delegate, 65 DownloadTargetDeterminerDelegate* delegate,
64 const content::DownloadTargetCallback& callback) 66 const content::DownloadTargetCallback& callback)
65 : next_state_(STATE_GENERATE_TARGET_PATH), 67 : next_state_(STATE_GENERATE_TARGET_PATH),
66 should_prompt_(false), 68 should_prompt_(false),
69 should_notify_extensions_(false),
67 create_directory_(false), 70 create_directory_(false),
68 conflict_action_(download->GetForcedFilePath().empty() ? 71 conflict_action_(DownloadPathReservationTracker::OVERWRITE),
69 DownloadPathReservationTracker::UNIQUIFY :
70 DownloadPathReservationTracker::OVERWRITE),
71 danger_type_(download->GetDangerType()), 72 danger_type_(download->GetDangerType()),
73 virtual_path_(initial_virtual_path),
72 download_(download), 74 download_(download),
75 is_resumption_(download_->GetLastReason() !=
76 content::DOWNLOAD_INTERRUPT_REASON_NONE &&
77 !initial_virtual_path.empty()),
73 download_prefs_(download_prefs), 78 download_prefs_(download_prefs),
74 delegate_(delegate), 79 delegate_(delegate),
75 last_selected_directory_(last_selected_directory), 80 last_selected_directory_(last_selected_directory),
76 completion_callback_(callback), 81 completion_callback_(callback),
77 weak_ptr_factory_(this) { 82 weak_ptr_factory_(this) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 DCHECK(download_); 84 DCHECK(download_);
80 DCHECK(delegate); 85 DCHECK(delegate);
81 download_->AddObserver(this); 86 download_->AddObserver(this);
82 87
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // return QUIT_DOLOOP. In this case, an inner DoLoop() may complete the target 135 // return QUIT_DOLOOP. In this case, an inner DoLoop() may complete the target
131 // determination and delete |this|. 136 // determination and delete |this|.
132 137
133 if (result == COMPLETE) 138 if (result == COMPLETE)
134 ScheduleCallbackAndDeleteSelf(); 139 ScheduleCallbackAndDeleteSelf();
135 } 140 }
136 141
137 DownloadTargetDeterminer::Result 142 DownloadTargetDeterminer::Result
138 DownloadTargetDeterminer::DoGenerateTargetPath() { 143 DownloadTargetDeterminer::DoGenerateTargetPath() {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 DCHECK(virtual_path_.empty());
141 DCHECK(local_path_.empty()); 145 DCHECK(local_path_.empty());
146 DCHECK(!should_prompt_);
147 DCHECK(!should_notify_extensions_);
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 Why is this a member variable rather than a local
asanka 2013/05/29 22:30:11 It's set here, but is read in DoNotifyExtensions()
148 DCHECK_EQ(DownloadPathReservationTracker::OVERWRITE, conflict_action_);
142 bool is_forced_path = !download_->GetForcedFilePath().empty(); 149 bool is_forced_path = !download_->GetForcedFilePath().empty();
143 150
144 next_state_ = STATE_NOTIFY_EXTENSIONS; 151 next_state_ = STATE_NOTIFY_EXTENSIONS;
145 152
146 // If we don't have a forced path, we should construct a path for the 153 if (!virtual_path_.empty() && HasPromptedForPath() && !is_forced_path) {
147 // download. Forced paths are only specified for programmatic downloads 154 // The download is being resumed and the user has already been prompted for
148 // (WebStore, Drag&Drop). Treat the path as a virtual path. We will eventually 155 // a path. Assume that it's okay to overwrite the file if there's a
149 // determine whether this is a local path and if not, figure out a local path. 156 // conflict and reuse the selection.
150 if (!is_forced_path) { 157 // Note: |virtual_path_| may already be uniquified. In this case setting
151 std::string default_filename( 158 // conflict_action_ to UNIQUIFY may cause additional levels of uniquifiers
159 // (e.g. "foo (1) (1).txt").
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 Why is this comment still relevant? If we prompte
asanka 2013/05/29 22:30:11 Yes. The comment was explaining why we aren't sett
160 should_prompt_ = ShouldPromptForDownload(virtual_path_);
161 } else if (!is_forced_path) {
162 // If we don't have a forced path, we should construct a path for the
163 // download. Forced paths are only specified for programmatic downloads
164 // (WebStore, Drag&Drop). Treat the path as a virtual path. We will
165 // eventually determine whether this is a local path and if not, figure out
166 // a local path.
167 std::string default_filename(
152 l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME)); 168 l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME));
153 base::FilePath generated_filename = net::GenerateFileName( 169 base::FilePath generated_filename = net::GenerateFileName(
154 download_->GetURL(), 170 download_->GetURL(),
155 download_->GetContentDisposition(), 171 download_->GetContentDisposition(),
156 GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset), 172 GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset),
157 download_->GetSuggestedFilename(), 173 download_->GetSuggestedFilename(),
158 download_->GetMimeType(), 174 download_->GetMimeType(),
159 default_filename); 175 default_filename);
160 should_prompt_ = ShouldPromptForDownload(generated_filename); 176 should_prompt_ = ShouldPromptForDownload(generated_filename);
161 base::FilePath target_directory; 177 base::FilePath target_directory;
162 if (should_prompt_ && !last_selected_directory_.empty()) { 178 if (should_prompt_ && !last_selected_directory_.empty()) {
163 DCHECK(!download_prefs_->IsDownloadPathManaged()); 179 DCHECK(!download_prefs_->IsDownloadPathManaged());
164 // If the user is going to be prompted and the user has been prompted 180 // If the user is going to be prompted and the user has been prompted
165 // before, then always prefer the last directory that the user selected. 181 // before, then always prefer the last directory that the user selected.
166 target_directory = last_selected_directory_; 182 target_directory = last_selected_directory_;
167 } else { 183 } else {
168 target_directory = download_prefs_->DownloadPath(); 184 target_directory = download_prefs_->DownloadPath();
169 } 185 }
170 virtual_path_ = target_directory.Append(generated_filename); 186 virtual_path_ = target_directory.Append(generated_filename);
187 conflict_action_ = DownloadPathReservationTracker::UNIQUIFY;
188 should_notify_extensions_ = true;
171 } else { 189 } else {
172 DCHECK(!should_prompt_); 190 DCHECK(!should_prompt_);
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 nit: Feels a little redundant with identical DCHEC
asanka 2013/05/29 22:30:11 Done.
173 virtual_path_ = download_->GetForcedFilePath(); 191 virtual_path_ = download_->GetForcedFilePath();
192 // If this is a resumed download which was previously interrupted due to an
193 // issue with the forced path, the user is still not prompted. If the path
194 // supplied to a programmatic download is invalid, then the caller needs to
195 // intervene.
174 } 196 }
175 DCHECK(virtual_path_.IsAbsolute()); 197 DCHECK(virtual_path_.IsAbsolute());
176 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe(); 198 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe();
177 199
178 // If the download is DOA, don't bother going any further. This would be the 200 // If the download is DOA, don't bother going any further. This would be the
179 // case for a download that failed to initialize (e.g. the initial temporary 201 // case for a download that failed to initialize (e.g. the initial temporary
180 // file couldn't be created because both the downloads directory and the 202 // file couldn't be created because both the downloads directory and the
181 // temporary directory are unwriteable). 203 // temporary directory are unwriteable).
182 // 204 //
183 // A virtual path is determined for DOA downloads for display purposes. This 205 // A virtual path is determined for DOA downloads for display purposes. This
184 // is why this check is performed here instead of at the start. 206 // is why this check is performed here instead of at the start.
185 if (!download_->IsInProgress()) 207 if (!download_->IsInProgress())
186 return COMPLETE; 208 return COMPLETE;
187 return CONTINUE; 209 return CONTINUE;
188 } 210 }
189 211
190 DownloadTargetDeterminer::Result 212 DownloadTargetDeterminer::Result
191 DownloadTargetDeterminer::DoNotifyExtensions() { 213 DownloadTargetDeterminer::DoNotifyExtensions() {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 DCHECK(!virtual_path_.empty()); 215 DCHECK(!virtual_path_.empty());
194 216
195 next_state_ = STATE_RESERVE_VIRTUAL_PATH; 217 next_state_ = STATE_RESERVE_VIRTUAL_PATH;
196 218
197 // If the target path is forced or if we don't have an extensions event 219 if (!should_notify_extensions_)
198 // router, then proceed with the original path.
199 if (!download_->GetForcedFilePath().empty())
200 return CONTINUE; 220 return CONTINUE;
201 221
202 delegate_->NotifyExtensions(download_, virtual_path_, 222 delegate_->NotifyExtensions(download_, virtual_path_,
203 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, 223 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone,
204 weak_ptr_factory_.GetWeakPtr())); 224 weak_ptr_factory_.GetWeakPtr()));
205 return QUIT_DOLOOP; 225 return QUIT_DOLOOP;
206 } 226 }
207 227
208 void DownloadTargetDeterminer::NotifyExtensionsDone( 228 void DownloadTargetDeterminer::NotifyExtensionsDone(
209 const base::FilePath& suggested_path, 229 const base::FilePath& suggested_path,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 DownloadTargetDeterminer::Result 360 DownloadTargetDeterminer::Result
341 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { 361 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() {
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
343 363
344 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; 364 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH;
345 365
346 // Checking if there are prior visits to the referrer is only necessary if the 366 // Checking if there are prior visits to the referrer is only necessary if the
347 // danger level of the download depends on the file type. This excludes cases 367 // danger level of the download depends on the file type. This excludes cases
348 // where the download has already been deemed dangerous, or where the user is 368 // where the download has already been deemed dangerous, or where the user is
349 // going to be prompted or where this is a programmatic download. 369 // going to be prompted or where this is a programmatic download.
350 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS || 370 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)
351 should_prompt_ ||
352 !download_->GetForcedFilePath().empty()) {
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 Sorry, confused. Why remove the other two checks?
asanka 2013/05/29 22:30:11 The checks were moved to IsDangerousFile().
353 return CONTINUE; 371 return CONTINUE;
354 }
355 372
356 // Assume that: 373 // Assume that:
357 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...) 374 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...)
358 // I.e. having visited a referrer only lowers a file's danger level. 375 // I.e. having visited a referrer only lowers a file's danger level.
359 if (IsDangerousFile(NO_VISITS_TO_REFERRER)) { 376 if (IsDangerousFile(NO_VISITS_TO_REFERRER)) {
360 // Only need to ping the history DB if the download would be considered safe 377 // Only need to ping the history DB if the download would be considered safe
361 // if there are prior visits and is considered dangerous otherwise. 378 // if there are prior visits and is considered dangerous otherwise.
362 if (!IsDangerousFile(VISITED_REFERRER)) { 379 if (!IsDangerousFile(VISITED_REFERRER)) {
363 // HistoryServiceFactory redirects incognito profiles to on-record 380 // HistoryServiceFactory redirects incognito profiles to on-record
364 // profiles. There's no history for on-record profiles in unit_tests. 381 // profiles. There's no history for on-record profiles in unit_tests.
(...skipping 26 matching lines...) Expand all
391 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 408 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
392 DoLoop(); 409 DoLoop();
393 } 410 }
394 411
395 DownloadTargetDeterminer::Result 412 DownloadTargetDeterminer::Result
396 DownloadTargetDeterminer::DoDetermineIntermediatePath() { 413 DownloadTargetDeterminer::DoDetermineIntermediatePath() {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
398 DCHECK(!virtual_path_.empty()); 415 DCHECK(!virtual_path_.empty());
399 DCHECK(!local_path_.empty()); 416 DCHECK(!local_path_.empty());
400 DCHECK(intermediate_path_.empty()); 417 DCHECK(intermediate_path_.empty());
418 DCHECK(!virtual_path_.MatchesExtension(FILE_PATH_LITERAL(".crdownload")));
419 DCHECK(!local_path_.MatchesExtension(FILE_PATH_LITERAL(".crdownload")));
401 420
402 next_state_ = STATE_NONE; 421 next_state_ = STATE_NONE;
403 422
404 // Note that the intermediate filename is always uniquified (i.e. if a file by 423 // Note that the intermediate filename is always uniquified (i.e. if a file by
405 // the same name exists, it is never overwritten). Therefore the code below 424 // the same name exists, it is never overwritten). Therefore the code below
406 // does not attempt to find a name that doesn't conflict with an existing 425 // does not attempt to find a name that doesn't conflict with an existing
407 // file. 426 // file.
408 427
409 // If the actual target of the download is a virtual path, then the local path 428 // If the actual target of the download is a virtual path, then the local path
410 // is considered to point to a temporary path. A separate intermediate path is 429 // is considered to point to a temporary path. A separate intermediate path is
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 DCHECK(download_); 476 DCHECK(download_);
458 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe() 477 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe()
459 << " Local:" << local_path_.AsUTF8Unsafe() 478 << " Local:" << local_path_.AsUTF8Unsafe()
460 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe() 479 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe()
461 << " Should prompt:" << should_prompt_ 480 << " Should prompt:" << should_prompt_
462 << " Danger type:" << danger_type_; 481 << " Danger type:" << danger_type_;
463 MessageLoop::current()->PostTask( 482 MessageLoop::current()->PostTask(
464 FROM_HERE, 483 FROM_HERE,
465 base::Bind(completion_callback_, 484 base::Bind(completion_callback_,
466 local_path_, 485 local_path_,
467 (should_prompt_ ? DownloadItem::TARGET_DISPOSITION_PROMPT : 486 (HasPromptedForPath()
468 DownloadItem::TARGET_DISPOSITION_OVERWRITE), 487 ? DownloadItem::TARGET_DISPOSITION_PROMPT
488 : DownloadItem::TARGET_DISPOSITION_OVERWRITE),
469 danger_type_, 489 danger_type_,
470 intermediate_path_)); 490 intermediate_path_));
471 completion_callback_.Reset(); 491 completion_callback_.Reset();
472 delete this; 492 delete this;
473 } 493 }
474 494
475 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() { 495 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() {
476 // Path substitution failed. 496 // Path substitution failed.
477 virtual_path_.clear(); 497 virtual_path_.clear();
478 local_path_.clear(); 498 local_path_.clear();
479 intermediate_path_.clear(); 499 intermediate_path_.clear();
480 ScheduleCallbackAndDeleteSelf(); 500 ScheduleCallbackAndDeleteSelf();
481 } 501 }
482 502
483 Profile* DownloadTargetDeterminer::GetProfile() { 503 Profile* DownloadTargetDeterminer::GetProfile() {
484 DCHECK(download_->GetBrowserContext()); 504 DCHECK(download_->GetBrowserContext());
485 return Profile::FromBrowserContext(download_->GetBrowserContext()); 505 return Profile::FromBrowserContext(download_->GetBrowserContext());
486 } 506 }
487 507
488 bool DownloadTargetDeterminer::ShouldPromptForDownload( 508 bool DownloadTargetDeterminer::ShouldPromptForDownload(
489 const base::FilePath& filename) { 509 const base::FilePath& filename) const {
510 if (is_resumption_) {
511 // If the target disposition or prefs require prompting, the user has
512 // already been prompted. Try to respect the user's selection, unless we've
513 // discovered that the target path cannot be used for some reason.
514 content::DownloadInterruptReason reason = download_->GetLastReason();
515 return (reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED ||
516 reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE ||
517 reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE);
518 }
519
490 // If the download path is forced, don't prompt. 520 // If the download path is forced, don't prompt.
491 if (!download_->GetForcedFilePath().empty()) { 521 if (!download_->GetForcedFilePath().empty()) {
492 // 'Save As' downloads shouldn't have a forced path. 522 // 'Save As' downloads shouldn't have a forced path.
493 DCHECK_NE(DownloadItem::TARGET_DISPOSITION_PROMPT, 523 DCHECK(is_resumption_ ||
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 This portion of the DCHECK seems strange, since th
asanka 2013/05/29 22:30:11 Done.
494 download_->GetTargetDisposition()); 524 (DownloadItem::TARGET_DISPOSITION_PROMPT !=
525 download_->GetTargetDisposition()));
495 return false; 526 return false;
496 } 527 }
497 528
498 // Don't ask where to save if the download path is managed. Even if the user 529 // Don't ask where to save if the download path is managed. Even if the user
499 // wanted to be prompted for "all" downloads, or if this was a 'Save As' 530 // wanted to be prompted for "all" downloads, or if this was a 'Save As'
500 // download. 531 // download.
501 if (download_prefs_->IsDownloadPathManaged()) 532 if (download_prefs_->IsDownloadPathManaged())
502 return false; 533 return false;
503 534
504 // Prompt if this is a 'Save As' download. 535 // Prompt if this is a 'Save As' download.
(...skipping 14 matching lines...) Expand all
519 return true; 550 return true;
520 551
521 // Otherwise, don't prompt. Note that the user might still be prompted if 552 // Otherwise, don't prompt. Note that the user might still be prompted if
522 // there are unresolved conflicts during path reservation (e.g. due to the 553 // there are unresolved conflicts during path reservation (e.g. due to the
523 // target path being unwriteable or because there are too many conflicting 554 // target path being unwriteable or because there are too many conflicting
524 // files), or if an extension signals that the user be prompted on a filename 555 // files), or if an extension signals that the user be prompted on a filename
525 // conflict. 556 // conflict.
526 return false; 557 return false;
527 } 558 }
528 559
560 bool DownloadTargetDeterminer::HasPromptedForPath() const {
561 return should_prompt_ ||
562 (is_resumption_ && download_->GetTargetDisposition() ==
563 DownloadItem::TARGET_DISPOSITION_PROMPT);
564 }
565
529 bool DownloadTargetDeterminer::IsDangerousFile(PriorVisitsToReferrer visits) { 566 bool DownloadTargetDeterminer::IsDangerousFile(PriorVisitsToReferrer visits) {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
568
569 // If the user has has been prompted, assume that the user has approved the
570 // download. Programmatic downloads are considered safe unless it contains
Randy Smith (Not in Mondays) 2013/05/24 01:53:55 nit: "it contains" -> "they contain" (or "A progra
asanka 2013/05/29 22:30:11 Done.
571 // malware.
572 if (HasPromptedForPath() || !download_->GetForcedFilePath().empty())
573 return false;
574
531 const bool is_extension_download = 575 const bool is_extension_download =
532 download_crx_util::IsExtensionDownload(*download_); 576 download_crx_util::IsExtensionDownload(*download_);
533 577
534 // User-initiated extension downloads from pref-whitelisted sources are not 578 // User-initiated extension downloads from pref-whitelisted sources are not
535 // considered dangerous. 579 // considered dangerous.
536 if (download_->HasUserGesture() && 580 if (download_->HasUserGesture() &&
537 is_extension_download && 581 is_extension_download &&
538 download_crx_util::OffStoreInstallAllowedByPrefs( 582 download_crx_util::OffStoreInstallAllowedByPrefs(
539 GetProfile(), *download_)) { 583 GetProfile(), *download_)) {
540 return false; 584 return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 void DownloadTargetDeterminer::OnDownloadDestroyed( 621 void DownloadTargetDeterminer::OnDownloadDestroyed(
578 DownloadItem* download) { 622 DownloadItem* download) {
579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
580 DCHECK_EQ(download_, download); 624 DCHECK_EQ(download_, download);
581 CancelOnFailureAndDeleteSelf(); 625 CancelOnFailureAndDeleteSelf();
582 } 626 }
583 627
584 // static 628 // static
585 void DownloadTargetDeterminer::Start( 629 void DownloadTargetDeterminer::Start(
586 content::DownloadItem* download, 630 content::DownloadItem* download,
631 const base::FilePath& initial_virtual_path,
587 DownloadPrefs* download_prefs, 632 DownloadPrefs* download_prefs,
588 const base::FilePath& last_selected_directory, 633 const base::FilePath& last_selected_directory,
589 DownloadTargetDeterminerDelegate* delegate, 634 DownloadTargetDeterminerDelegate* delegate,
590 const content::DownloadTargetCallback& callback) { 635 const content::DownloadTargetCallback& callback) {
591 // DownloadTargetDeterminer owns itself and will self destruct when the job is 636 // DownloadTargetDeterminer owns itself and will self destruct when the job is
592 // complete or the download item is destroyed. The callback is always invoked 637 // complete or the download item is destroyed. The callback is always invoked
593 // asynchronously. 638 // asynchronously.
594 new DownloadTargetDeterminer(download, download_prefs, 639 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs,
595 last_selected_directory, delegate, callback); 640 last_selected_directory, delegate, callback);
596 } 641 }
597 642
598 // static 643 // static
599 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( 644 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath(
600 const base::FilePath& suggested_path) { 645 const base::FilePath& suggested_path) {
601 return base::FilePath(suggested_path.value() + 646 return base::FilePath(suggested_path.value() +
602 FILE_PATH_LITERAL(".crdownload")); 647 FILE_PATH_LITERAL(".crdownload"));
603 } 648 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698