 Chromium Code Reviews
 Chromium Code Reviews Issue 55063002:
  Prefer opening PDF downloads in the browser.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 55063002:
  Prefer opening PDF downloads in the browser.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 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/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" | 
| 10 #include "base/time/time.h" | 10 #include "base/time/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/extensions/webstore_installer.h" | 15 #include "chrome/browser/extensions/webstore_installer.h" | 
| 16 #include "chrome/browser/history/history_service.h" | 16 #include "chrome/browser/history/history_service.h" | 
| 17 #include "chrome/browser/history/history_service_factory.h" | 17 #include "chrome/browser/history/history_service_factory.h" | 
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" | 
| 19 #include "chrome/common/extensions/feature_switch.h" | 19 #include "chrome/common/extensions/feature_switch.h" | 
| 20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" | 
| 21 #include "content/public/browser/browser_context.h" | 21 #include "content/public/browser/browser_context.h" | 
| 22 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" | 
| 23 #include "content/public/browser/download_interrupt_reasons.h" | 23 #include "content/public/browser/download_interrupt_reasons.h" | 
| 24 #include "extensions/common/constants.h" | 24 #include "extensions/common/constants.h" | 
| 25 #include "grit/generated_resources.h" | 25 #include "grit/generated_resources.h" | 
| 26 #include "net/base/mime_util.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 | 
| 30 #if defined(ENABLE_PLUGINS) | |
| 31 #include "chrome/browser/plugins/plugin_prefs.h" | |
| 32 #include "content/public/browser/plugin_service.h" | |
| 33 #include "content/public/common/webplugininfo.h" | |
| 34 #endif | |
| 35 | |
| 29 using content::BrowserThread; | 36 using content::BrowserThread; | 
| 30 using content::DownloadItem; | 37 using content::DownloadItem; | 
| 31 | 38 | 
| 32 namespace { | 39 namespace { | 
| 33 | 40 | 
| 34 const base::FilePath::CharType kCrdownloadSuffix[] = | 41 const base::FilePath::CharType kCrdownloadSuffix[] = | 
| 35 FILE_PATH_LITERAL(".crdownload"); | 42 FILE_PATH_LITERAL(".crdownload"); | 
| 36 | 43 | 
| 37 // Condenses the results from HistoryService::GetVisibleVisitCountToHost() to a | 44 // Condenses the results from HistoryService::GetVisibleVisitCountToHost() to a | 
| 38 // single bool. A host is considered visited before if prior visible visits were | 45 // single bool. A host is considered visited before if prior visible visits were | 
| 39 // found in history and the first such visit was earlier than the most recent | 46 // found in history and the first such visit was earlier than the most recent | 
| 40 // midnight. | 47 // midnight. | 
| 41 void VisitCountsToVisitedBefore( | 48 void VisitCountsToVisitedBefore( | 
| 42 const base::Callback<void(bool)>& callback, | 49 const base::Callback<void(bool)>& callback, | 
| 43 HistoryService::Handle unused_handle, | 50 HistoryService::Handle unused_handle, | 
| 44 bool found_visits, | 51 bool found_visits, | 
| 45 int count, | 52 int count, | 
| 46 base::Time first_visit) { | 53 base::Time first_visit) { | 
| 47 callback.Run( | 54 callback.Run( | 
| 48 found_visits && count > 0 && | 55 found_visits && count > 0 && | 
| 49 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); | 56 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); | 
| 50 } | 57 } | 
| 51 | 58 | 
| 59 #if defined(ENABLE_PLUGINS) | |
| 60 typedef std::vector<content::WebPluginInfo> PluginVector; | |
| 61 | |
| 62 bool IsSafePluginAvailableForProfile(scoped_ptr<PluginVector> plugins, | |
| 63 Profile* profile) { | |
| 64 using content::WebPluginInfo; | |
| 65 | |
| 66 if (plugins->size() == 0) | |
| 67 return false; | |
| 68 | |
| 69 scoped_refptr<PluginPrefs> plugin_prefs = PluginPrefs::GetForProfile(profile); | |
| 70 if (!plugin_prefs) | |
| 71 return false; | |
| 72 | |
| 73 for (PluginVector::iterator plugin = plugins->begin(); | |
| 74 plugin != plugins->end(); ++plugin) { | |
| 75 if (plugin_prefs->IsPluginEnabled(*plugin) && | |
| 76 (plugin->type == WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS || | |
| 77 plugin->type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS)) | |
| 78 return true; | |
| 79 } | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 base::Callback<bool(Profile*)> GetPluginListVerifier( | |
| 84 const std::string& mime_type) { | |
| 85 DCHECK(!mime_type.empty()); | |
| 86 | |
| 87 scoped_ptr<PluginVector> plugins(new PluginVector); | |
| 88 content::PluginService* plugin_service = | |
| 89 content::PluginService::GetInstance(); | |
| 90 if (plugin_service) | |
| 91 plugin_service->GetPluginInfoArray( | |
| 92 GURL(), mime_type, false, plugins.get(), NULL); | |
| 93 return base::Bind(&IsSafePluginAvailableForProfile, base::Passed(&plugins)); | |
| 94 } | |
| 95 #endif // ENABLE_PLUGINS | |
| 
Randy Smith (Not in Mondays)
2013/11/04 19:53:26
I'm a bit torn about this code organization.  On t
 
asanka
2013/11/04 21:20:11
I tried that, but it still seemed a bit confusing.
 | |
| 96 | |
| 52 } // namespace | 97 } // namespace | 
| 53 | 98 | 
| 99 DownloadTargetInfo::DownloadTargetInfo() | |
| 100 : is_filetype_handled_securely(false) {} | |
| 101 | |
| 102 DownloadTargetInfo::~DownloadTargetInfo() {} | |
| 103 | |
| 54 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { | 104 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { | 
| 55 } | 105 } | 
| 56 | 106 | 
| 57 DownloadTargetDeterminer::DownloadTargetDeterminer( | 107 DownloadTargetDeterminer::DownloadTargetDeterminer( | 
| 58 DownloadItem* download, | 108 DownloadItem* download, | 
| 59 const base::FilePath& initial_virtual_path, | 109 const base::FilePath& initial_virtual_path, | 
| 60 DownloadPrefs* download_prefs, | 110 DownloadPrefs* download_prefs, | 
| 61 DownloadTargetDeterminerDelegate* delegate, | 111 DownloadTargetDeterminerDelegate* delegate, | 
| 62 const content::DownloadTargetCallback& callback) | 112 const CompletionCallback& callback) | 
| 63 : next_state_(STATE_GENERATE_TARGET_PATH), | 113 : next_state_(STATE_GENERATE_TARGET_PATH), | 
| 64 should_prompt_(false), | 114 should_prompt_(false), | 
| 65 should_notify_extensions_(false), | 115 should_notify_extensions_(false), | 
| 66 create_target_directory_(false), | 116 create_target_directory_(false), | 
| 67 conflict_action_(DownloadPathReservationTracker::OVERWRITE), | 117 conflict_action_(DownloadPathReservationTracker::OVERWRITE), | 
| 68 danger_type_(download->GetDangerType()), | 118 danger_type_(download->GetDangerType()), | 
| 69 virtual_path_(initial_virtual_path), | 119 virtual_path_(initial_virtual_path), | 
| 120 is_filetype_handled_securely_(false), | |
| 70 download_(download), | 121 download_(download), | 
| 71 is_resumption_(download_->GetLastReason() != | 122 is_resumption_(download_->GetLastReason() != | 
| 72 content::DOWNLOAD_INTERRUPT_REASON_NONE && | 123 content::DOWNLOAD_INTERRUPT_REASON_NONE && | 
| 73 !initial_virtual_path.empty()), | 124 !initial_virtual_path.empty()), | 
| 74 download_prefs_(download_prefs), | 125 download_prefs_(download_prefs), | 
| 75 delegate_(delegate), | 126 delegate_(delegate), | 
| 76 completion_callback_(callback), | 127 completion_callback_(callback), | 
| 77 weak_ptr_factory_(this) { | 128 weak_ptr_factory_(this) { | 
| 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 79 DCHECK(download_); | 130 DCHECK(download_); | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 105 break; | 156 break; | 
| 106 case STATE_RESERVE_VIRTUAL_PATH: | 157 case STATE_RESERVE_VIRTUAL_PATH: | 
| 107 result = DoReserveVirtualPath(); | 158 result = DoReserveVirtualPath(); | 
| 108 break; | 159 break; | 
| 109 case STATE_PROMPT_USER_FOR_DOWNLOAD_PATH: | 160 case STATE_PROMPT_USER_FOR_DOWNLOAD_PATH: | 
| 110 result = DoPromptUserForDownloadPath(); | 161 result = DoPromptUserForDownloadPath(); | 
| 111 break; | 162 break; | 
| 112 case STATE_DETERMINE_LOCAL_PATH: | 163 case STATE_DETERMINE_LOCAL_PATH: | 
| 113 result = DoDetermineLocalPath(); | 164 result = DoDetermineLocalPath(); | 
| 114 break; | 165 break; | 
| 166 case STATE_DETERMINE_MIME_TYPE: | |
| 167 result = DoDetermineMimeType(); | |
| 168 break; | |
| 169 case STATE_DETERMINE_IF_HANDLED_BY_BROWSER: | |
| 170 result = DoDetermineIfHandledByBrowser(); | |
| 171 break; | |
| 115 case STATE_CHECK_DOWNLOAD_URL: | 172 case STATE_CHECK_DOWNLOAD_URL: | 
| 116 result = DoCheckDownloadUrl(); | 173 result = DoCheckDownloadUrl(); | 
| 117 break; | 174 break; | 
| 118 case STATE_DETERMINE_INTERMEDIATE_PATH: | 175 case STATE_DETERMINE_INTERMEDIATE_PATH: | 
| 119 result = DoDetermineIntermediatePath(); | 176 result = DoDetermineIntermediatePath(); | 
| 120 break; | 177 break; | 
| 121 case STATE_CHECK_VISITED_REFERRER_BEFORE: | 178 case STATE_CHECK_VISITED_REFERRER_BEFORE: | 
| 122 result = DoCheckVisitedReferrerBefore(); | 179 result = DoCheckVisitedReferrerBefore(); | 
| 123 break; | 180 break; | 
| 124 case STATE_NONE: | 181 case STATE_NONE: | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 download_prefs_->SetSaveFilePath(virtual_path_.DirName()); | 355 download_prefs_->SetSaveFilePath(virtual_path_.DirName()); | 
| 299 DoLoop(); | 356 DoLoop(); | 
| 300 } | 357 } | 
| 301 | 358 | 
| 302 DownloadTargetDeterminer::Result | 359 DownloadTargetDeterminer::Result | 
| 303 DownloadTargetDeterminer::DoDetermineLocalPath() { | 360 DownloadTargetDeterminer::DoDetermineLocalPath() { | 
| 304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 305 DCHECK(!virtual_path_.empty()); | 362 DCHECK(!virtual_path_.empty()); | 
| 306 DCHECK(local_path_.empty()); | 363 DCHECK(local_path_.empty()); | 
| 307 | 364 | 
| 308 next_state_ = STATE_CHECK_DOWNLOAD_URL; | 365 next_state_ = STATE_DETERMINE_MIME_TYPE; | 
| 309 | 366 | 
| 310 delegate_->DetermineLocalPath( | 367 delegate_->DetermineLocalPath( | 
| 311 download_, | 368 download_, | 
| 312 virtual_path_, | 369 virtual_path_, | 
| 313 base::Bind(&DownloadTargetDeterminer::DetermineLocalPathDone, | 370 base::Bind(&DownloadTargetDeterminer::DetermineLocalPathDone, | 
| 314 weak_ptr_factory_.GetWeakPtr())); | 371 weak_ptr_factory_.GetWeakPtr())); | 
| 315 return QUIT_DOLOOP; | 372 return QUIT_DOLOOP; | 
| 316 } | 373 } | 
| 317 | 374 | 
| 318 void DownloadTargetDeterminer::DetermineLocalPathDone( | 375 void DownloadTargetDeterminer::DetermineLocalPathDone( | 
| 319 const base::FilePath& local_path) { | 376 const base::FilePath& local_path) { | 
| 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 321 DVLOG(20) << "Local path: " << local_path.AsUTF8Unsafe(); | 378 DVLOG(20) << "Local path: " << local_path.AsUTF8Unsafe(); | 
| 322 if (local_path.empty()) { | 379 if (local_path.empty()) { | 
| 323 // Path subsitution failed. | 380 // Path subsitution failed. | 
| 324 CancelOnFailureAndDeleteSelf(); | 381 CancelOnFailureAndDeleteSelf(); | 
| 325 return; | 382 return; | 
| 326 } | 383 } | 
| 327 local_path_ = local_path; | 384 local_path_ = local_path; | 
| 328 DoLoop(); | 385 DoLoop(); | 
| 329 } | 386 } | 
| 330 | 387 | 
| 331 DownloadTargetDeterminer::Result | 388 DownloadTargetDeterminer::Result | 
| 389 DownloadTargetDeterminer::DoDetermineMimeType() { | |
| 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 391 DCHECK(!virtual_path_.empty()); | |
| 392 DCHECK(!local_path_.empty()); | |
| 393 DCHECK(mime_type_.empty()); | |
| 394 | |
| 395 next_state_ = STATE_DETERMINE_IF_HANDLED_BY_BROWSER; | |
| 396 | |
| 397 if (virtual_path_ == local_path_) { | |
| 398 delegate_->GetFileMimeType( | |
| 399 local_path_, | |
| 400 base::Bind(&DownloadTargetDeterminer::DetermineMimeTypeDone, | |
| 401 weak_ptr_factory_.GetWeakPtr())); | |
| 402 return QUIT_DOLOOP; | |
| 403 } | |
| 404 return CONTINUE; | |
| 405 } | |
| 406 | |
| 407 void DownloadTargetDeterminer::DetermineMimeTypeDone( | |
| 408 const std::string& mime_type) { | |
| 409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 410 DVLOG(20) << "MIME type: " << mime_type; | |
| 411 mime_type_ = mime_type; | |
| 412 DoLoop(); | |
| 413 } | |
| 414 | |
| 415 DownloadTargetDeterminer::Result | |
| 416 DownloadTargetDeterminer::DoDetermineIfHandledByBrowser() { | |
| 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 418 DCHECK(!virtual_path_.empty()); | |
| 419 DCHECK(!local_path_.empty()); | |
| 420 DCHECK(!is_filetype_handled_securely_); | |
| 421 | |
| 422 next_state_ = STATE_CHECK_DOWNLOAD_URL; | |
| 423 | |
| 424 if (mime_type_.empty()) | |
| 425 return CONTINUE; | |
| 426 | |
| 427 if (net::IsSupportedMimeType(mime_type_)) { | |
| 428 is_filetype_handled_securely_ = true; | |
| 429 return CONTINUE; | |
| 430 } | |
| 431 | |
| 432 BrowserThread::PostTaskAndReplyWithResult( | |
| 433 BrowserThread::IO, | |
| 434 FROM_HERE, | |
| 435 base::Bind(&GetPluginListVerifier, mime_type_), | |
| 436 base::Bind(&DownloadTargetDeterminer::DetermineIfHandledByBrowserDone, | |
| 437 weak_ptr_factory_.GetWeakPtr())); | |
| 438 return QUIT_DOLOOP; | |
| 439 } | |
| 440 | |
| 441 void DownloadTargetDeterminer::DetermineIfHandledByBrowserDone( | |
| 442 const base::Callback<bool(Profile*)>& callback) { | |
| 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 444 is_filetype_handled_securely_ = callback.Run(GetProfile()); | |
| 445 DVLOG(20) << "Is file type handled securely: " | |
| 446 << is_filetype_handled_securely_; | |
| 447 DoLoop(); | |
| 448 } | |
| 449 | |
| 450 DownloadTargetDeterminer::Result | |
| 332 DownloadTargetDeterminer::DoCheckDownloadUrl() { | 451 DownloadTargetDeterminer::DoCheckDownloadUrl() { | 
| 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 334 DCHECK(!virtual_path_.empty()); | 453 DCHECK(!virtual_path_.empty()); | 
| 335 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; | 454 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; | 
| 336 delegate_->CheckDownloadUrl( | 455 delegate_->CheckDownloadUrl( | 
| 337 download_, | 456 download_, | 
| 338 virtual_path_, | 457 virtual_path_, | 
| 339 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, | 458 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, | 
| 340 weak_ptr_factory_.GetWeakPtr())); | 459 weak_ptr_factory_.GetWeakPtr())); | 
| 341 return QUIT_DOLOOP; | 460 return QUIT_DOLOOP; | 
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 return COMPLETE; | 596 return COMPLETE; | 
| 478 } | 597 } | 
| 479 | 598 | 
| 480 void DownloadTargetDeterminer::ScheduleCallbackAndDeleteSelf() { | 599 void DownloadTargetDeterminer::ScheduleCallbackAndDeleteSelf() { | 
| 481 DCHECK(download_); | 600 DCHECK(download_); | 
| 482 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe() | 601 DVLOG(20) << "Scheduling callback. Virtual:" << virtual_path_.AsUTF8Unsafe() | 
| 483 << " Local:" << local_path_.AsUTF8Unsafe() | 602 << " Local:" << local_path_.AsUTF8Unsafe() | 
| 484 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe() | 603 << " Intermediate:" << intermediate_path_.AsUTF8Unsafe() | 
| 485 << " Should prompt:" << should_prompt_ | 604 << " Should prompt:" << should_prompt_ | 
| 486 << " Danger type:" << danger_type_; | 605 << " Danger type:" << danger_type_; | 
| 606 scoped_ptr<DownloadTargetInfo> target_info(new DownloadTargetInfo); | |
| 607 | |
| 608 target_info->target_path = local_path_; | |
| 609 target_info->target_disposition = | |
| 610 (HasPromptedForPath() || should_prompt_ | |
| 611 ? DownloadItem::TARGET_DISPOSITION_PROMPT | |
| 612 : DownloadItem::TARGET_DISPOSITION_OVERWRITE); | |
| 613 target_info->danger_type = danger_type_; | |
| 614 target_info->intermediate_path = intermediate_path_; | |
| 615 target_info->mime_type = mime_type_; | |
| 616 target_info->is_filetype_handled_securely = is_filetype_handled_securely_; | |
| 
Randy Smith (Not in Mondays)
2013/11/04 19:53:26
Long-term thought: One of the goals I had for the
 
asanka
2013/11/04 21:20:11
Yup. We can look at it when we revisit the handlin
 | |
| 617 | |
| 487 base::MessageLoop::current()->PostTask( | 618 base::MessageLoop::current()->PostTask( | 
| 488 FROM_HERE, | 619 FROM_HERE, base::Bind(completion_callback_, base::Passed(&target_info))); | 
| 489 base::Bind(completion_callback_, | |
| 490 local_path_, | |
| 491 (HasPromptedForPath() || should_prompt_ | |
| 492 ? DownloadItem::TARGET_DISPOSITION_PROMPT | |
| 493 : DownloadItem::TARGET_DISPOSITION_OVERWRITE), | |
| 494 danger_type_, | |
| 495 intermediate_path_)); | |
| 496 completion_callback_.Reset(); | 620 completion_callback_.Reset(); | 
| 497 delete this; | 621 delete this; | 
| 498 } | 622 } | 
| 499 | 623 | 
| 500 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() { | 624 void DownloadTargetDeterminer::CancelOnFailureAndDeleteSelf() { | 
| 501 // Path substitution failed. | 625 // Path substitution failed. | 
| 502 virtual_path_.clear(); | 626 virtual_path_.clear(); | 
| 503 local_path_.clear(); | 627 local_path_.clear(); | 
| 504 intermediate_path_.clear(); | 628 intermediate_path_.clear(); | 
| 505 ScheduleCallbackAndDeleteSelf(); | 629 ScheduleCallbackAndDeleteSelf(); | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 } | 748 } | 
| 625 | 749 | 
| 626 void DownloadTargetDeterminer::OnDownloadDestroyed( | 750 void DownloadTargetDeterminer::OnDownloadDestroyed( | 
| 627 DownloadItem* download) { | 751 DownloadItem* download) { | 
| 628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 629 DCHECK_EQ(download_, download); | 753 DCHECK_EQ(download_, download); | 
| 630 CancelOnFailureAndDeleteSelf(); | 754 CancelOnFailureAndDeleteSelf(); | 
| 631 } | 755 } | 
| 632 | 756 | 
| 633 // static | 757 // static | 
| 634 void DownloadTargetDeterminer::Start( | 758 void DownloadTargetDeterminer::Start(content::DownloadItem* download, | 
| 635 content::DownloadItem* download, | 759 const base::FilePath& initial_virtual_path, | 
| 636 const base::FilePath& initial_virtual_path, | 760 DownloadPrefs* download_prefs, | 
| 637 DownloadPrefs* download_prefs, | 761 DownloadTargetDeterminerDelegate* delegate, | 
| 638 DownloadTargetDeterminerDelegate* delegate, | 762 const CompletionCallback& callback) { | 
| 639 const content::DownloadTargetCallback& callback) { | |
| 640 // DownloadTargetDeterminer owns itself and will self destruct when the job is | 763 // DownloadTargetDeterminer owns itself and will self destruct when the job is | 
| 641 // complete or the download item is destroyed. The callback is always invoked | 764 // complete or the download item is destroyed. The callback is always invoked | 
| 642 // asynchronously. | 765 // asynchronously. | 
| 643 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs, | 766 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs, | 
| 644 delegate, callback); | 767 delegate, callback); | 
| 645 } | 768 } | 
| 646 | 769 | 
| 647 // static | 770 // static | 
| 648 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( | 771 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( | 
| 649 const base::FilePath& suggested_path) { | 772 const base::FilePath& suggested_path) { | 
| 650 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 773 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 
| 651 } | 774 } | 
| OLD | NEW |