| 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 |