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

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: Merge with r201622 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),
67 create_directory_(false), 69 create_directory_(false),
68 conflict_action_(download->GetForcedFilePath().empty() ? 70 conflict_action_(download->GetForcedFilePath().empty() ?
69 DownloadPathReservationTracker::UNIQUIFY : 71 DownloadPathReservationTracker::UNIQUIFY :
70 DownloadPathReservationTracker::OVERWRITE), 72 DownloadPathReservationTracker::OVERWRITE),
71 danger_type_(download->GetDangerType()), 73 danger_type_(download->GetDangerType()),
74 virtual_path_(initial_virtual_path),
72 download_(download), 75 download_(download),
76 is_resumption_(download_->GetLastReason() !=
77 content::DOWNLOAD_INTERRUPT_REASON_NONE &&
78 !initial_virtual_path.empty()),
73 download_prefs_(download_prefs), 79 download_prefs_(download_prefs),
74 delegate_(delegate), 80 delegate_(delegate),
75 last_selected_directory_(last_selected_directory), 81 last_selected_directory_(last_selected_directory),
76 completion_callback_(callback), 82 completion_callback_(callback),
77 weak_ptr_factory_(this) { 83 weak_ptr_factory_(this) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 DCHECK(download_); 85 DCHECK(download_);
80 DCHECK(delegate); 86 DCHECK(delegate);
81 download_->AddObserver(this); 87 download_->AddObserver(this);
82 88
(...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 136 // return QUIT_DOLOOP. In this case, an inner DoLoop() may complete the target
131 // determination and delete |this|. 137 // determination and delete |this|.
132 138
133 if (result == COMPLETE) 139 if (result == COMPLETE)
134 ScheduleCallbackAndDeleteSelf(); 140 ScheduleCallbackAndDeleteSelf();
135 } 141 }
136 142
137 DownloadTargetDeterminer::Result 143 DownloadTargetDeterminer::Result
138 DownloadTargetDeterminer::DoGenerateTargetPath() { 144 DownloadTargetDeterminer::DoGenerateTargetPath() {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 DCHECK(virtual_path_.empty());
141 DCHECK(local_path_.empty()); 146 DCHECK(local_path_.empty());
142 bool is_forced_path = !download_->GetForcedFilePath().empty(); 147 bool is_forced_path = !download_->GetForcedFilePath().empty();
143 148
144 next_state_ = STATE_NOTIFY_EXTENSIONS; 149 next_state_ = STATE_NOTIFY_EXTENSIONS;
145 150
146 // If we don't have a forced path, we should construct a path for the 151 if (!virtual_path_.empty()) {
147 // download. Forced paths are only specified for programmatic downloads 152 DCHECK(!is_forced_path || virtual_path_ == download_->GetForcedFilePath());
148 // (WebStore, Drag&Drop). Treat the path as a virtual path. We will eventually 153 DCHECK(!should_prompt_);
149 // determine whether this is a local path and if not, figure out a local path. 154 // The download is being resumed and virtual_path_ is the path that was
150 if (!is_forced_path) { 155 // determined prior to the interruption. If the path was selected by the
151 std::string default_filename( 156 // user or if is a forced path, then assume that it's okay to overwrite the
157 // target.
158 // Note: |virtual_path_| may already be uniquified. In this case setting
159 // conflict_action_ to UNIQUIFY may cause additional levels of uniquifiers
160 // (e.g. "foo (1) (1).txt").
161 conflict_action_ = (is_forced_path || HasPromptedForPath())
162 ? DownloadPathReservationTracker::OVERWRITE
163 : DownloadPathReservationTracker::PROMPT;
164 should_prompt_ = ShouldPromptForDownload(virtual_path_);
165 } else if (!is_forced_path) {
166 // If we don't have a forced path, we should construct a path for the
167 // download. Forced paths are only specified for programmatic downloads
168 // (WebStore, Drag&Drop). Treat the path as a virtual path. We will
169 // eventually determine whether this is a local path and if not, figure out
170 // a local path.
171 std::string default_filename(
152 l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME)); 172 l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME));
153 base::FilePath generated_filename = net::GenerateFileName( 173 base::FilePath generated_filename = net::GenerateFileName(
154 download_->GetURL(), 174 download_->GetURL(),
155 download_->GetContentDisposition(), 175 download_->GetContentDisposition(),
156 GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset), 176 GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset),
157 download_->GetSuggestedFilename(), 177 download_->GetSuggestedFilename(),
158 download_->GetMimeType(), 178 download_->GetMimeType(),
159 default_filename); 179 default_filename);
160 should_prompt_ = ShouldPromptForDownload(generated_filename); 180 should_prompt_ = ShouldPromptForDownload(generated_filename);
161 base::FilePath target_directory; 181 base::FilePath target_directory;
(...skipping 26 matching lines...) Expand all
188 } 208 }
189 209
190 DownloadTargetDeterminer::Result 210 DownloadTargetDeterminer::Result
191 DownloadTargetDeterminer::DoNotifyExtensions() { 211 DownloadTargetDeterminer::DoNotifyExtensions() {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 DCHECK(!virtual_path_.empty()); 213 DCHECK(!virtual_path_.empty());
194 214
195 next_state_ = STATE_RESERVE_VIRTUAL_PATH; 215 next_state_ = STATE_RESERVE_VIRTUAL_PATH;
196 216
197 // If the target path is forced or if we don't have an extensions event 217 // If the target path is forced or if we don't have an extensions event
198 // router, then proceed with the original path. 218 // router, then proceed with the original path. Also don't notify extensions
199 if (!download_->GetForcedFilePath().empty()) 219 // for a resumed download since extensions would have been notified once
220 // already.
221 if (!download_->GetForcedFilePath().empty() || is_resumption_)
200 return CONTINUE; 222 return CONTINUE;
201 223
202 delegate_->NotifyExtensions(download_, virtual_path_, 224 delegate_->NotifyExtensions(download_, virtual_path_,
203 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, 225 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone,
204 weak_ptr_factory_.GetWeakPtr())); 226 weak_ptr_factory_.GetWeakPtr()));
205 return QUIT_DOLOOP; 227 return QUIT_DOLOOP;
206 } 228 }
207 229
208 void DownloadTargetDeterminer::NotifyExtensionsDone( 230 void DownloadTargetDeterminer::NotifyExtensionsDone(
209 const base::FilePath& suggested_path, 231 const base::FilePath& suggested_path,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { 363 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() {
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
343 365
344 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; 366 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH;
345 367
346 // Checking if there are prior visits to the referrer is only necessary if the 368 // 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 369 // 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 370 // 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. 371 // going to be prompted or where this is a programmatic download.
350 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS || 372 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS ||
351 should_prompt_ || 373 HasPromptedForPath() ||
352 !download_->GetForcedFilePath().empty()) { 374 !download_->GetForcedFilePath().empty()) {
asanka 2013/05/23 20:30:38 This logic was incorporated into IsDangerousFile()
353 return CONTINUE; 375 return CONTINUE;
354 } 376 }
355 377
356 // Assume that: 378 // Assume that:
357 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...) 379 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...)
358 // I.e. having visited a referrer only lowers a file's danger level. 380 // I.e. having visited a referrer only lowers a file's danger level.
359 if (IsDangerousFile(NO_VISITS_TO_REFERRER)) { 381 if (IsDangerousFile(NO_VISITS_TO_REFERRER)) {
360 // Only need to ping the history DB if the download would be considered safe 382 // 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. 383 // if there are prior visits and is considered dangerous otherwise.
362 if (!IsDangerousFile(VISITED_REFERRER)) { 384 if (!IsDangerousFile(VISITED_REFERRER)) {
(...skipping 28 matching lines...) Expand all
391 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 413 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
392 DoLoop(); 414 DoLoop();
393 } 415 }
394 416
395 DownloadTargetDeterminer::Result 417 DownloadTargetDeterminer::Result
396 DownloadTargetDeterminer::DoDetermineIntermediatePath() { 418 DownloadTargetDeterminer::DoDetermineIntermediatePath() {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
398 DCHECK(!virtual_path_.empty()); 420 DCHECK(!virtual_path_.empty());
399 DCHECK(!local_path_.empty()); 421 DCHECK(!local_path_.empty());
400 DCHECK(intermediate_path_.empty()); 422 DCHECK(intermediate_path_.empty());
423 DCHECK(!virtual_path_.MatchesExtension(FILE_PATH_LITERAL(".crdownload")));
424 DCHECK(!local_path_.MatchesExtension(FILE_PATH_LITERAL(".crdownload")));
401 425
402 next_state_ = STATE_NONE; 426 next_state_ = STATE_NONE;
403 427
404 // Note that the intermediate filename is always uniquified (i.e. if a file by 428 // 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 429 // 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 430 // does not attempt to find a name that doesn't conflict with an existing
407 // file. 431 // file.
408 432
409 // If the actual target of the download is a virtual path, then the local path 433 // 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 434 // 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_); 481 DCHECK(download_);
458 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe() 482 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe()
459 << " Local:" << local_path_.AsUTF8Unsafe() 483 << " Local:" << local_path_.AsUTF8Unsafe()
460 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe() 484 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe()
461 << " Should prompt:" << should_prompt_ 485 << " Should prompt:" << should_prompt_
462 << " Danger type:" << danger_type_; 486 << " Danger type:" << danger_type_;
463 MessageLoop::current()->PostTask( 487 MessageLoop::current()->PostTask(
464 FROM_HERE, 488 FROM_HERE,
465 base::Bind(completion_callback_, 489 base::Bind(completion_callback_,
466 local_path_, 490 local_path_,
467 (should_prompt_ ? DownloadItem::TARGET_DISPOSITION_PROMPT : 491 (HasPromptedForPath()
468 DownloadItem::TARGET_DISPOSITION_OVERWRITE), 492 ? DownloadItem::TARGET_DISPOSITION_PROMPT
493 : DownloadItem::TARGET_DISPOSITION_OVERWRITE),
469 danger_type_, 494 danger_type_,
470 intermediate_path_)); 495 intermediate_path_));
471 completion_callback_.Reset(); 496 completion_callback_.Reset();
472 delete this; 497 delete this;
473 } 498 }
474 499
475 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() { 500 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() {
476 // Path substitution failed. 501 // Path substitution failed.
477 virtual_path_.clear(); 502 virtual_path_.clear();
478 local_path_.clear(); 503 local_path_.clear();
479 intermediate_path_.clear(); 504 intermediate_path_.clear();
480 ScheduleCallbackAndDeleteSelf(); 505 ScheduleCallbackAndDeleteSelf();
481 } 506 }
482 507
483 Profile* DownloadTargetDeterminer::GetProfile() { 508 Profile* DownloadTargetDeterminer::GetProfile() {
484 DCHECK(download_->GetBrowserContext()); 509 DCHECK(download_->GetBrowserContext());
485 return Profile::FromBrowserContext(download_->GetBrowserContext()); 510 return Profile::FromBrowserContext(download_->GetBrowserContext());
486 } 511 }
487 512
488 bool DownloadTargetDeterminer::ShouldPromptForDownload( 513 bool DownloadTargetDeterminer::ShouldPromptForDownload(
489 const base::FilePath& filename) { 514 const base::FilePath& filename) const {
515 if (is_resumption_) {
516 // If the target disposition or prefs require prompting, the user has
517 // already been prompted. Try to respect the user's selection, unless we've
518 // discovered that the target path cannot be used for some reason.
519 content::DownloadInterruptReason reason = download_->GetLastReason();
520 return (reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED ||
521 reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE ||
522 reason == content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE);
523 }
524
490 // If the download path is forced, don't prompt. 525 // If the download path is forced, don't prompt.
491 if (!download_->GetForcedFilePath().empty()) { 526 if (!download_->GetForcedFilePath().empty()) {
492 // 'Save As' downloads shouldn't have a forced path. 527 // 'Save As' downloads shouldn't have a forced path.
493 DCHECK_NE(DownloadItem::TARGET_DISPOSITION_PROMPT, 528 DCHECK(is_resumption_ ||
494 download_->GetTargetDisposition()); 529 (DownloadItem::TARGET_DISPOSITION_PROMPT !=
530 download_->GetTargetDisposition()));
495 return false; 531 return false;
496 } 532 }
497 533
498 // Don't ask where to save if the download path is managed. Even if the user 534 // 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' 535 // wanted to be prompted for "all" downloads, or if this was a 'Save As'
500 // download. 536 // download.
501 if (download_prefs_->IsDownloadPathManaged()) 537 if (download_prefs_->IsDownloadPathManaged())
502 return false; 538 return false;
503 539
504 // Prompt if this is a 'Save As' download. 540 // Prompt if this is a 'Save As' download.
(...skipping 14 matching lines...) Expand all
519 return true; 555 return true;
520 556
521 // Otherwise, don't prompt. Note that the user might still be prompted if 557 // 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 558 // there are unresolved conflicts during path reservation (e.g. due to the
523 // target path being unwriteable or because there are too many conflicting 559 // 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 560 // files), or if an extension signals that the user be prompted on a filename
525 // conflict. 561 // conflict.
526 return false; 562 return false;
527 } 563 }
528 564
565 bool DownloadTargetDeterminer::HasPromptedForPath() const {
566 return should_prompt_ ||
567 (is_resumption_ && download_->GetTargetDisposition() ==
568 DownloadItem::TARGET_DISPOSITION_PROMPT);
569 }
570
529 bool DownloadTargetDeterminer::IsDangerousFile(PriorVisitsToReferrer visits) { 571 bool DownloadTargetDeterminer::IsDangerousFile(PriorVisitsToReferrer visits) {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 572 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
531 const bool is_extension_download = 573 const bool is_extension_download =
532 download_crx_util::IsExtensionDownload(*download_); 574 download_crx_util::IsExtensionDownload(*download_);
533 575
534 // User-initiated extension downloads from pref-whitelisted sources are not 576 // User-initiated extension downloads from pref-whitelisted sources are not
535 // considered dangerous. 577 // considered dangerous.
536 if (download_->HasUserGesture() && 578 if (download_->HasUserGesture() &&
537 is_extension_download && 579 is_extension_download &&
538 download_crx_util::OffStoreInstallAllowedByPrefs( 580 download_crx_util::OffStoreInstallAllowedByPrefs(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 void DownloadTargetDeterminer::OnDownloadDestroyed( 619 void DownloadTargetDeterminer::OnDownloadDestroyed(
578 DownloadItem* download) { 620 DownloadItem* download) {
579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
580 DCHECK_EQ(download_, download); 622 DCHECK_EQ(download_, download);
581 CancelOnFailureAndDeleteSelf(); 623 CancelOnFailureAndDeleteSelf();
582 } 624 }
583 625
584 // static 626 // static
585 void DownloadTargetDeterminer::Start( 627 void DownloadTargetDeterminer::Start(
586 content::DownloadItem* download, 628 content::DownloadItem* download,
629 const base::FilePath& initial_virtual_path,
587 DownloadPrefs* download_prefs, 630 DownloadPrefs* download_prefs,
588 const base::FilePath& last_selected_directory, 631 const base::FilePath& last_selected_directory,
589 DownloadTargetDeterminerDelegate* delegate, 632 DownloadTargetDeterminerDelegate* delegate,
590 const content::DownloadTargetCallback& callback) { 633 const content::DownloadTargetCallback& callback) {
591 // DownloadTargetDeterminer owns itself and will self destruct when the job is 634 // DownloadTargetDeterminer owns itself and will self destruct when the job is
592 // complete or the download item is destroyed. The callback is always invoked 635 // complete or the download item is destroyed. The callback is always invoked
593 // asynchronously. 636 // asynchronously.
594 new DownloadTargetDeterminer(download, download_prefs, 637 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs,
595 last_selected_directory, delegate, callback); 638 last_selected_directory, delegate, callback);
596 } 639 }
597 640
598 // static 641 // static
599 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( 642 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath(
600 const base::FilePath& suggested_path) { 643 const base::FilePath& suggested_path) {
601 return base::FilePath(suggested_path.value() + 644 return base::FilePath(suggested_path.value() +
602 FILE_PATH_LITERAL(".crdownload")); 645 FILE_PATH_LITERAL(".crdownload"));
603 } 646 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_target_determiner.h ('k') | chrome/browser/download/download_target_determiner_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698