OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_manager.h" | 5 #include "chrome/browser/download/download_manager.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/path_service.h" | |
12 #include "base/rand_util.h" | 11 #include "base/rand_util.h" |
13 #include "base/stl_util-inl.h" | 12 #include "base/stl_util-inl.h" |
14 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
15 #include "base/sys_string_conversions.h" | 14 #include "base/sys_string_conversions.h" |
16 #include "base/task.h" | 15 #include "base/task.h" |
17 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
18 #include "build/build_config.h" | 17 #include "build/build_config.h" |
19 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/download/download_create_info.h" | 19 #include "chrome/browser/download/download_create_info.h" |
21 #include "chrome/browser/download/download_extensions.h" | 20 #include "chrome/browser/download/download_extensions.h" |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 // the suggested path on the UI thread. | 357 // the suggested path on the UI thread. |
359 // We can only access preferences on the UI thread, so check the download path | 358 // We can only access preferences on the UI thread, so check the download path |
360 // now and pass the value to the FILE thread. | 359 // now and pass the value to the FILE thread. |
361 BrowserThread::PostTask( | 360 BrowserThread::PostTask( |
362 BrowserThread::FILE, FROM_HERE, | 361 BrowserThread::FILE, FROM_HERE, |
363 NewRunnableMethod( | 362 NewRunnableMethod( |
364 this, | 363 this, |
365 &DownloadManager::CheckIfSuggestedPathExists, | 364 &DownloadManager::CheckIfSuggestedPathExists, |
366 download->id(), | 365 download->id(), |
367 state, | 366 state, |
368 download_prefs()->download_path())); | 367 download_prefs()->download_path(), |
| 368 download_prefs()->GetDefaultDownloadDirectory())); |
369 } | 369 } |
370 | 370 |
371 void DownloadManager::CheckIfSuggestedPathExists(int32 download_id, | 371 void DownloadManager::CheckIfSuggestedPathExists( |
372 DownloadStateInfo state, | 372 int32 download_id, |
373 const FilePath& default_path) { | 373 DownloadStateInfo state, |
| 374 const FilePath& download_save_dir, |
| 375 const FilePath& default_download_dir) { |
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
375 | 377 |
376 // Make sure the default download directory exists. | 378 FilePath save_dir; |
377 // TODO(phajdan.jr): only create the directory when we're sure the user | 379 if (ChooseSavableDirectory( |
378 // is going to save there and not to another directory of his choice. | 380 FilePath(), download_save_dir, default_download_dir, &save_dir)) |
379 file_util::CreateDirectory(default_path); | |
380 | |
381 // Check writability of the suggested path. If we can't write to it, default | |
382 // to the user's "My Documents" directory. We'll prompt them in this case. | |
383 FilePath dir = state.suggested_path.DirName(); | |
384 FilePath filename = state.suggested_path.BaseName(); | |
385 if (!file_util::PathIsWritable(dir)) { | |
386 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; | |
387 state.prompt_user_for_save_location = true; | 381 state.prompt_user_for_save_location = true; |
388 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); | 382 state.suggested_path = save_dir.Append(state.suggested_path.BaseName()); |
389 state.suggested_path = state.suggested_path.Append(filename); | |
390 } | |
391 | 383 |
392 // If the download is deemed dangerous, we'll use a temporary name for it. | 384 // If the download is deemed dangerous, we'll use a temporary name for it. |
393 if (state.IsDangerous()) { | 385 if (state.IsDangerous()) { |
394 state.target_name = FilePath(state.suggested_path).BaseName(); | 386 state.target_name = state.suggested_path.BaseName(); |
395 // Create a temporary file to hold the file until the user approves its | 387 // Create a temporary file to hold the file until the user approves its |
396 // download. | 388 // download. |
397 FilePath::StringType file_name; | 389 FilePath::StringType file_name; |
398 FilePath path; | 390 FilePath path; |
399 #if defined(OS_WIN) | 391 #if defined(OS_WIN) |
400 string16 unconfirmed_prefix = | 392 string16 unconfirmed_prefix = |
401 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 393 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
402 #else | 394 #else |
403 std::string unconfirmed_prefix = | 395 std::string unconfirmed_prefix = |
404 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 396 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
405 #endif | 397 #endif |
406 | 398 |
407 while (path.empty()) { | 399 while (path.empty()) { |
408 base::SStringPrintf( | 400 base::SStringPrintf( |
409 &file_name, | 401 &file_name, |
410 unconfirmed_prefix.append( | 402 unconfirmed_prefix.append( |
411 FILE_PATH_LITERAL(" %d.crdownload")).c_str(), | 403 FILE_PATH_LITERAL(" %d.crdownload")).c_str(), |
412 base::RandInt(0, 100000)); | 404 base::RandInt(0, 100000)); |
413 path = dir.Append(file_name); | 405 path = state.suggested_path.DirName().Append(file_name); |
414 if (file_util::PathExists(path)) | 406 if (file_util::PathExists(path)) |
415 path = FilePath(); | 407 path = FilePath(); |
416 } | 408 } |
417 state.suggested_path = path; | 409 state.suggested_path = path; |
418 } else { | 410 } else { |
419 // Do not add the path uniquifier if we are saving to a specific path as in | 411 // Do not add the path uniquifier if we are saving to a specific path as in |
420 // the drag-out case. | 412 // the drag-out case. |
421 if (state.force_file_name.empty()) { | 413 if (state.force_file_name.empty()) { |
422 state.path_uniquifier = download_util::GetUniquePathNumberWithCrDownload( | 414 state.path_uniquifier = download_util::GetUniquePathNumberWithCrDownload( |
423 state.suggested_path); | 415 state.suggested_path); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 // FileSelectionCancelled(). | 485 // FileSelectionCancelled(). |
494 int32* id_ptr = new int32; | 486 int32* id_ptr = new int32; |
495 *id_ptr = download_id; | 487 *id_ptr = download_id; |
496 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, | 488 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, |
497 string16(), | 489 string16(), |
498 suggested_path, | 490 suggested_path, |
499 &file_type_info, 0, FILE_PATH_LITERAL(""), | 491 &file_type_info, 0, FILE_PATH_LITERAL(""), |
500 contents, owning_window, | 492 contents, owning_window, |
501 reinterpret_cast<void*>(id_ptr)); | 493 reinterpret_cast<void*>(id_ptr)); |
502 FOR_EACH_OBSERVER(Observer, observers_, | 494 FOR_EACH_OBSERVER(Observer, observers_, |
503 SelectFileDialogDisplayed(download_id)); | 495 SelectFileDialogDisplayed(download_id, suggested_path)); |
504 } else { | 496 } else { |
505 // No prompting for download, just continue with the suggested name. | 497 // No prompting for download, just continue with the suggested name. |
506 ContinueDownloadWithPath(download, suggested_path); | 498 ContinueDownloadWithPath(download, suggested_path); |
507 } | 499 } |
508 } | 500 } |
509 | 501 |
510 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { | 502 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { |
511 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
512 | 504 |
513 DownloadItem* download = new DownloadItem(this, *info, | 505 DownloadItem* download = new DownloadItem(this, *info, |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 } | 637 } |
646 | 638 |
647 void DownloadManager::AssertNotInQueues(DownloadItem* download) { | 639 void DownloadManager::AssertNotInQueues(DownloadItem* download) { |
648 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 640 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
649 CHECK(!ContainsKey(downloads_, download)); | 641 CHECK(!ContainsKey(downloads_, download)); |
650 CHECK(!ContainsKey(active_downloads_, download->id())); | 642 CHECK(!ContainsKey(active_downloads_, download->id())); |
651 CHECK(!ContainsKey(in_progress_, download->id())); | 643 CHECK(!ContainsKey(in_progress_, download->id())); |
652 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | 644 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
653 } | 645 } |
654 | 646 |
| 647 // static |
| 648 bool DownloadManager::ChooseSavableDirectory( |
| 649 const FilePath& website_save_dir, |
| 650 const FilePath& download_save_dir, |
| 651 const FilePath& default_download_dir, |
| 652 FilePath* save_dir) { |
| 653 bool prompt_dialog = false; |
| 654 if (file_util::PathIsWritable(website_save_dir)) { |
| 655 // If the default html/websites save folder exists, |
| 656 // then use the default h5Btml/websites save folder. |
| 657 *save_dir = website_save_dir; |
| 658 } else if (file_util::PathIsWritable(download_save_dir)) { |
| 659 // If the default html/websites save folder does not exist |
| 660 // but the default download folder exists, |
| 661 // then use the default download folder. |
| 662 *save_dir = download_save_dir; |
| 663 } else { |
| 664 // If both the above folders do not exist, |
| 665 // use the user's "Downloads" folder. |
| 666 *save_dir = default_download_dir; |
| 667 prompt_dialog = true; |
| 668 if (!file_util::PathIsWritable(*save_dir)) { |
| 669 VLOG(1) << "Cannot find the user's writable \"Downloads\" folder."; |
| 670 // Create the |download_save_dir| folder if we cannot get |
| 671 // the user's writable "Downloads" folder (This will be a rare case). |
| 672 *save_dir = download_save_dir; |
| 673 } |
| 674 // Make sure that the folder does exist. |
| 675 if (!file_util::CreateDirectory(*save_dir)) |
| 676 LOG(ERROR) << "Failed to create " << (*save_dir).value(); |
| 677 } |
| 678 return prompt_dialog; |
| 679 } |
| 680 |
655 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { | 681 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { |
656 // If we don't have all the data, the download is not ready for | 682 // If we don't have all the data, the download is not ready for |
657 // completion. | 683 // completion. |
658 if (!download->all_data_saved()) | 684 if (!download->all_data_saved()) |
659 return false; | 685 return false; |
660 | 686 |
661 // If the download is dangerous, but not yet validated, it's not ready for | 687 // If the download is dangerous, but not yet validated, it's not ready for |
662 // completion. | 688 // completion. |
663 if (download->safety_state() == DownloadItem::DANGEROUS) | 689 if (download->safety_state() == DownloadItem::DANGEROUS) |
664 return false; | 690 return false; |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 observed_download_manager_->RemoveObserver(this); | 1287 observed_download_manager_->RemoveObserver(this); |
1262 } | 1288 } |
1263 | 1289 |
1264 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1290 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
1265 observing_download_manager_->NotifyModelChanged(); | 1291 observing_download_manager_->NotifyModelChanged(); |
1266 } | 1292 } |
1267 | 1293 |
1268 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1294 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
1269 observed_download_manager_ = NULL; | 1295 observed_download_manager_ = NULL; |
1270 } | 1296 } |
OLD | NEW |