OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/save_package.h" | 5 #include "chrome/browser/download/save_package.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/i18n/file_util_icu.h" | 9 #include "base/i18n/file_util_icu.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/stl_util-inl.h" | 12 #include "base/stl_util-inl.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "base/task.h" | 14 #include "base/task.h" |
15 #include "base/thread.h" | 15 #include "base/thread.h" |
16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/chrome_thread.h" |
17 #include "chrome/browser/download/download_item_model.h" | 18 #include "chrome/browser/download/download_item_model.h" |
18 #include "chrome/browser/download/download_manager.h" | 19 #include "chrome/browser/download/download_manager.h" |
19 #include "chrome/browser/download/download_shelf.h" | 20 #include "chrome/browser/download/download_shelf.h" |
20 #include "chrome/browser/download/save_file.h" | 21 #include "chrome/browser/download/save_file.h" |
21 #include "chrome/browser/download/save_file_manager.h" | 22 #include "chrome/browser/download/save_file_manager.h" |
22 #include "chrome/browser/download/save_item.h" | 23 #include "chrome/browser/download/save_item.h" |
23 #include "chrome/browser/net/url_request_context_getter.h" | 24 #include "chrome/browser/net/url_request_context_getter.h" |
24 #include "chrome/browser/profile.h" | 25 #include "chrome/browser/profile.h" |
25 #include "chrome/browser/renderer_host/render_process_host.h" | 26 #include "chrome/browser/renderer_host/render_process_host.h" |
26 #include "chrome/browser/renderer_host/render_view_host.h" | 27 #include "chrome/browser/renderer_host/render_view_host.h" |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 FilePath final_name = saved_main_directory_path_.Append(generated_name); | 472 FilePath final_name = saved_main_directory_path_.Append(generated_name); |
472 save_item->Rename(final_name); | 473 save_item->Rename(final_name); |
473 } else { | 474 } else { |
474 // It is the main HTML file, use the name chosen by the user. | 475 // It is the main HTML file, use the name chosen by the user. |
475 save_item->Rename(saved_main_file_path_); | 476 save_item->Rename(saved_main_file_path_); |
476 } | 477 } |
477 | 478 |
478 // If the save source is from file system, inform SaveFileManager to copy | 479 // If the save source is from file system, inform SaveFileManager to copy |
479 // corresponding file to the file path which this SaveItem specifies. | 480 // corresponding file to the file path which this SaveItem specifies. |
480 if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) { | 481 if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) { |
481 file_manager_->file_loop()->PostTask(FROM_HERE, | 482 ChromeThread::PostTask( |
| 483 ChromeThread::FILE, FROM_HERE, |
482 NewRunnableMethod(file_manager_, | 484 NewRunnableMethod(file_manager_, |
483 &SaveFileManager::SaveLocalFile, | 485 &SaveFileManager::SaveLocalFile, |
484 save_item->url(), | 486 save_item->url(), |
485 save_item->save_id(), | 487 save_item->save_id(), |
486 tab_id())); | 488 tab_id())); |
487 return; | 489 return; |
488 } | 490 } |
489 | 491 |
490 // Check whether we begin to require serialized HTML data. | 492 // Check whether we begin to require serialized HTML data. |
491 if (save_type_ == SAVE_AS_COMPLETE_HTML && wait_state_ == HTML_DATA) { | 493 if (save_type_ == SAVE_AS_COMPLETE_HTML && wait_state_ == HTML_DATA) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 // This vector contains the save ids of the save files which SaveFileManager | 579 // This vector contains the save ids of the save files which SaveFileManager |
578 // needs to remove from its save_file_map_. | 580 // needs to remove from its save_file_map_. |
579 SaveIDList save_ids; | 581 SaveIDList save_ids; |
580 for (SavedItemMap::iterator it = saved_success_items_.begin(); | 582 for (SavedItemMap::iterator it = saved_success_items_.begin(); |
581 it != saved_success_items_.end(); ++it) | 583 it != saved_success_items_.end(); ++it) |
582 save_ids.push_back(it->first); | 584 save_ids.push_back(it->first); |
583 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin(); | 585 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin(); |
584 it != saved_failed_items_.end(); ++it) | 586 it != saved_failed_items_.end(); ++it) |
585 save_ids.push_back(it->second->save_id()); | 587 save_ids.push_back(it->second->save_id()); |
586 | 588 |
587 file_manager_->file_loop()->PostTask(FROM_HERE, | 589 ChromeThread::PostTask( |
| 590 ChromeThread::FILE, FROM_HERE, |
588 NewRunnableMethod(file_manager_, | 591 NewRunnableMethod(file_manager_, |
589 &SaveFileManager::RemoveSavedFileFromFileMap, | 592 &SaveFileManager::RemoveSavedFileFromFileMap, |
590 save_ids)); | 593 save_ids)); |
591 | 594 |
592 finished_ = true; | 595 finished_ = true; |
593 wait_state_ = FAILED; | 596 wait_state_ = FAILED; |
594 | 597 |
595 // Inform the DownloadItem we have canceled whole save page job. | 598 // Inform the DownloadItem we have canceled whole save page job. |
596 download_->Cancel(false); | 599 download_->Cancel(false); |
597 } | 600 } |
598 | 601 |
599 void SavePackage::CheckFinish() { | 602 void SavePackage::CheckFinish() { |
600 if (in_process_count() || finished_) | 603 if (in_process_count() || finished_) |
601 return; | 604 return; |
602 | 605 |
603 FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML && | 606 FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML && |
604 saved_success_items_.size() > 1) ? | 607 saved_success_items_.size() > 1) ? |
605 saved_main_directory_path_ : FilePath(); | 608 saved_main_directory_path_ : FilePath(); |
606 | 609 |
607 // This vector contains the final names of all the successfully saved files | 610 // This vector contains the final names of all the successfully saved files |
608 // along with their save ids. It will be passed to SaveFileManager to do the | 611 // along with their save ids. It will be passed to SaveFileManager to do the |
609 // renaming job. | 612 // renaming job. |
610 FinalNameList final_names; | 613 FinalNameList final_names; |
611 for (SavedItemMap::iterator it = saved_success_items_.begin(); | 614 for (SavedItemMap::iterator it = saved_success_items_.begin(); |
612 it != saved_success_items_.end(); ++it) | 615 it != saved_success_items_.end(); ++it) |
613 final_names.push_back(std::make_pair(it->first, | 616 final_names.push_back(std::make_pair(it->first, |
614 it->second->full_path())); | 617 it->second->full_path())); |
615 | 618 |
616 file_manager_->file_loop()->PostTask(FROM_HERE, | 619 ChromeThread::PostTask( |
| 620 ChromeThread::FILE, FROM_HERE, |
617 NewRunnableMethod(file_manager_, | 621 NewRunnableMethod(file_manager_, |
618 &SaveFileManager::RenameAllFiles, | 622 &SaveFileManager::RenameAllFiles, |
619 final_names, | 623 final_names, |
620 dir, | 624 dir, |
621 tab_contents_->process()->id(), | 625 tab_contents_->process()->id(), |
622 tab_contents_->render_view_host()->routing_id())); | 626 tab_contents_->render_view_host()->routing_id())); |
623 } | 627 } |
624 | 628 |
625 // Successfully finished all items of this SavePackage. | 629 // Successfully finished all items of this SavePackage. |
626 void SavePackage::Finish() { | 630 void SavePackage::Finish() { |
627 // User may cancel the job when we're moving files to the final directory. | 631 // User may cancel the job when we're moving files to the final directory. |
628 if (canceled()) | 632 if (canceled()) |
629 return; | 633 return; |
630 | 634 |
631 wait_state_ = SUCCESSFUL; | 635 wait_state_ = SUCCESSFUL; |
632 finished_ = true; | 636 finished_ = true; |
633 | 637 |
634 // This vector contains the save ids of the save files which SaveFileManager | 638 // This vector contains the save ids of the save files which SaveFileManager |
635 // needs to remove from its save_file_map_. | 639 // needs to remove from its save_file_map_. |
636 SaveIDList save_ids; | 640 SaveIDList save_ids; |
637 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin(); | 641 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin(); |
638 it != saved_failed_items_.end(); ++it) | 642 it != saved_failed_items_.end(); ++it) |
639 save_ids.push_back(it->second->save_id()); | 643 save_ids.push_back(it->second->save_id()); |
640 | 644 |
641 file_manager_->file_loop()->PostTask(FROM_HERE, | 645 ChromeThread::PostTask( |
| 646 ChromeThread::FILE, FROM_HERE, |
642 NewRunnableMethod(file_manager_, | 647 NewRunnableMethod(file_manager_, |
643 &SaveFileManager::RemoveSavedFileFromFileMap, | 648 &SaveFileManager::RemoveSavedFileFromFileMap, |
644 save_ids)); | 649 save_ids)); |
645 | 650 |
646 download_->Finished(all_save_items_count_); | 651 download_->Finished(all_save_items_count_); |
647 | 652 |
648 NotificationService::current()->Notify( | 653 NotificationService::current()->Notify( |
649 NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | 654 NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
650 Source<SavePackage>(this), | 655 Source<SavePackage>(this), |
651 Details<GURL>(&page_url_)); | 656 Details<GURL>(&page_url_)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 | 732 |
728 CheckFinish(); | 733 CheckFinish(); |
729 } | 734 } |
730 | 735 |
731 void SavePackage::SaveCanceled(SaveItem* save_item) { | 736 void SavePackage::SaveCanceled(SaveItem* save_item) { |
732 // Call the RemoveSaveFile in UI thread. | 737 // Call the RemoveSaveFile in UI thread. |
733 file_manager_->RemoveSaveFile(save_item->save_id(), | 738 file_manager_->RemoveSaveFile(save_item->save_id(), |
734 save_item->url(), | 739 save_item->url(), |
735 this); | 740 this); |
736 if (save_item->save_id() != -1) | 741 if (save_item->save_id() != -1) |
737 file_manager_->file_loop()->PostTask(FROM_HERE, | 742 ChromeThread::PostTask( |
| 743 ChromeThread::FILE, FROM_HERE, |
738 NewRunnableMethod(file_manager_, | 744 NewRunnableMethod(file_manager_, |
739 &SaveFileManager::CancelSave, | 745 &SaveFileManager::CancelSave, |
740 save_item->save_id())); | 746 save_item->save_id())); |
741 } | 747 } |
742 | 748 |
743 // Initiate a saving job of a specific URL. We send the request to | 749 // Initiate a saving job of a specific URL. We send the request to |
744 // SaveFileManager, which will dispatch it to different approach according to | 750 // SaveFileManager, which will dispatch it to different approach according to |
745 // the save source. Parameter process_all_remaining_items indicates whether | 751 // the save source. Parameter process_all_remaining_items indicates whether |
746 // we need to save all remaining items. | 752 // we need to save all remaining items. |
747 void SavePackage::SaveNextFile(bool process_all_remaining_items) { | 753 void SavePackage::SaveNextFile(bool process_all_remaining_items) { |
(...skipping 21 matching lines...) Expand all Loading... |
769 this); | 775 this); |
770 } while (process_all_remaining_items && waiting_item_queue_.size()); | 776 } while (process_all_remaining_items && waiting_item_queue_.size()); |
771 } | 777 } |
772 | 778 |
773 | 779 |
774 // Open download page in windows explorer on file thread, to avoid blocking the | 780 // Open download page in windows explorer on file thread, to avoid blocking the |
775 // user interface. | 781 // user interface. |
776 void SavePackage::ShowDownloadInShell() { | 782 void SavePackage::ShowDownloadInShell() { |
777 DCHECK(file_manager_); | 783 DCHECK(file_manager_); |
778 DCHECK(finished_ && !canceled() && !saved_main_file_path_.empty()); | 784 DCHECK(finished_ && !canceled() && !saved_main_file_path_.empty()); |
779 DCHECK(MessageLoop::current() == file_manager_->ui_loop()); | 785 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
780 #if defined(OS_MACOSX) | 786 #if defined(OS_MACOSX) |
781 // Mac OS X requires opening downloads on the UI thread. | 787 // Mac OS X requires opening downloads on the UI thread. |
782 platform_util::ShowItemInFolder(saved_main_file_path_); | 788 platform_util::ShowItemInFolder(saved_main_file_path_); |
783 #else | 789 #else |
784 file_manager_->file_loop()->PostTask(FROM_HERE, | 790 ChromeThread::PostTask( |
| 791 ChromeThread::FILE, FROM_HERE, |
785 NewRunnableMethod(file_manager_, | 792 NewRunnableMethod(file_manager_, |
786 &SaveFileManager::OnShowSavedFileInShell, | 793 &SaveFileManager::OnShowSavedFileInShell, |
787 saved_main_file_path_)); | 794 saved_main_file_path_)); |
788 #endif | 795 #endif |
789 } | 796 } |
790 | 797 |
791 // Calculate the percentage of whole save page job. | 798 // Calculate the percentage of whole save page job. |
792 int SavePackage::PercentComplete() { | 799 int SavePackage::PercentComplete() { |
793 if (!all_save_items_count_) | 800 if (!all_save_items_count_) |
794 return 0; | 801 return 0; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 // Check current state. | 902 // Check current state. |
896 if (wait_state_ != HTML_DATA) | 903 if (wait_state_ != HTML_DATA) |
897 return; | 904 return; |
898 | 905 |
899 int id = tab_id(); | 906 int id = tab_id(); |
900 // If the all frames are finished saving, we need to close the | 907 // If the all frames are finished saving, we need to close the |
901 // remaining SaveItems. | 908 // remaining SaveItems. |
902 if (flag == webkit_glue::DomSerializerDelegate::ALL_FRAMES_ARE_FINISHED) { | 909 if (flag == webkit_glue::DomSerializerDelegate::ALL_FRAMES_ARE_FINISHED) { |
903 for (SaveUrlItemMap::iterator it = in_progress_items_.begin(); | 910 for (SaveUrlItemMap::iterator it = in_progress_items_.begin(); |
904 it != in_progress_items_.end(); ++it) { | 911 it != in_progress_items_.end(); ++it) { |
905 file_manager_->file_loop()->PostTask(FROM_HERE, | 912 ChromeThread::PostTask( |
| 913 ChromeThread::FILE, FROM_HERE, |
906 NewRunnableMethod(file_manager_, | 914 NewRunnableMethod(file_manager_, |
907 &SaveFileManager::SaveFinished, | 915 &SaveFileManager::SaveFinished, |
908 it->second->save_id(), | 916 it->second->save_id(), |
909 it->second->url(), | 917 it->second->url(), |
910 id, | 918 id, |
911 true)); | 919 true)); |
912 } | 920 } |
913 return; | 921 return; |
914 } | 922 } |
915 | 923 |
916 SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec()); | 924 SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec()); |
917 if (it == in_progress_items_.end()) | 925 if (it == in_progress_items_.end()) |
918 return; | 926 return; |
919 SaveItem* save_item = it->second; | 927 SaveItem* save_item = it->second; |
920 DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM); | 928 DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM); |
921 | 929 |
922 if (!data.empty()) { | 930 if (!data.empty()) { |
923 // Prepare buffer for saving HTML data. | 931 // Prepare buffer for saving HTML data. |
924 net::IOBuffer* new_data = new net::IOBuffer(data.size()); | 932 net::IOBuffer* new_data = new net::IOBuffer(data.size()); |
925 new_data->AddRef(); // We'll pass the buffer to SaveFileManager. | 933 new_data->AddRef(); // We'll pass the buffer to SaveFileManager. |
926 memcpy(new_data->data(), data.data(), data.size()); | 934 memcpy(new_data->data(), data.data(), data.size()); |
927 | 935 |
928 // Call write file functionality in file thread. | 936 // Call write file functionality in file thread. |
929 file_manager_->file_loop()->PostTask(FROM_HERE, | 937 ChromeThread::PostTask( |
| 938 ChromeThread::FILE, FROM_HERE, |
930 NewRunnableMethod(file_manager_, | 939 NewRunnableMethod(file_manager_, |
931 &SaveFileManager::UpdateSaveProgress, | 940 &SaveFileManager::UpdateSaveProgress, |
932 save_item->save_id(), | 941 save_item->save_id(), |
933 new_data, | 942 new_data, |
934 static_cast<int>(data.size()))); | 943 static_cast<int>(data.size()))); |
935 } | 944 } |
936 | 945 |
937 // Current frame is completed saving, call finish in file thread. | 946 // Current frame is completed saving, call finish in file thread. |
938 if (flag == webkit_glue::DomSerializerDelegate::CURRENT_FRAME_IS_FINISHED) { | 947 if (flag == webkit_glue::DomSerializerDelegate::CURRENT_FRAME_IS_FINISHED) { |
939 file_manager_->file_loop()->PostTask(FROM_HERE, | 948 ChromeThread::PostTask( |
| 949 ChromeThread::FILE, FROM_HERE, |
940 NewRunnableMethod(file_manager_, | 950 NewRunnableMethod(file_manager_, |
941 &SaveFileManager::SaveFinished, | 951 &SaveFileManager::SaveFinished, |
942 save_item->save_id(), | 952 save_item->save_id(), |
943 save_item->url(), | 953 save_item->url(), |
944 id, | 954 id, |
945 true)); | 955 true)); |
946 } | 956 } |
947 } | 957 } |
948 | 958 |
949 // Ask for all savable resource links from backend, include main frame and | 959 // Ask for all savable resource links from backend, include main frame and |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL); | 1084 save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL); |
1075 DCHECK(!(*save_file_path).empty()); | 1085 DCHECK(!(*save_file_path).empty()); |
1076 | 1086 |
1077 return FilePath::FromWStringHack(*save_file_path); | 1087 return FilePath::FromWStringHack(*save_file_path); |
1078 } | 1088 } |
1079 | 1089 |
1080 void SavePackage::GetSaveInfo() { | 1090 void SavePackage::GetSaveInfo() { |
1081 FilePath save_dir = | 1091 FilePath save_dir = |
1082 GetSaveDirPreference(tab_contents_->profile()->GetPrefs()); | 1092 GetSaveDirPreference(tab_contents_->profile()->GetPrefs()); |
1083 | 1093 |
1084 file_manager_->file_loop()->PostTask(FROM_HERE, | 1094 ChromeThread::PostTask( |
| 1095 ChromeThread::FILE, FROM_HERE, |
1085 new CreateDownloadDirectoryTask(save_dir, | 1096 new CreateDownloadDirectoryTask(save_dir, |
1086 method_factory_.NewRunnableMethod( | 1097 method_factory_.NewRunnableMethod( |
1087 &SavePackage::ContinueGetSaveInfo, save_dir), | 1098 &SavePackage::ContinueGetSaveInfo, save_dir), |
1088 MessageLoop::current())); | 1099 MessageLoop::current())); |
1089 // CreateDownloadDirectoryTask calls ContinueGetSaveInfo() below. | 1100 // CreateDownloadDirectoryTask calls ContinueGetSaveInfo() below. |
1090 } | 1101 } |
1091 | 1102 |
1092 void SavePackage::ContinueGetSaveInfo(FilePath save_dir) { | 1103 void SavePackage::ContinueGetSaveInfo(FilePath save_dir) { |
1093 // Use "Web Page, Complete" option as default choice of saving page. | 1104 // Use "Web Page, Complete" option as default choice of saving page. |
1094 int file_type_index = 2; | 1105 int file_type_index = 2; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 int index, void* params) { | 1259 int index, void* params) { |
1249 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); | 1260 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); |
1250 ContinueSave(save_params, path, index); | 1261 ContinueSave(save_params, path, index); |
1251 delete save_params; | 1262 delete save_params; |
1252 } | 1263 } |
1253 | 1264 |
1254 void SavePackage::FileSelectionCanceled(void* params) { | 1265 void SavePackage::FileSelectionCanceled(void* params) { |
1255 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); | 1266 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); |
1256 delete save_params; | 1267 delete save_params; |
1257 } | 1268 } |
OLD | NEW |