Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/download/save_package.h" | 5 #include "content/browser/download/save_package.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 user_canceled_(false), | 134 user_canceled_(false), |
| 135 disk_error_occurred_(false), | 135 disk_error_occurred_(false), |
| 136 save_type_(save_type), | 136 save_type_(save_type), |
| 137 all_save_items_count_(0), | 137 all_save_items_count_(0), |
| 138 wait_state_(INITIALIZE), | 138 wait_state_(INITIALIZE), |
| 139 tab_id_(web_contents->GetRenderProcessHost()->GetID()), | 139 tab_id_(web_contents->GetRenderProcessHost()->GetID()), |
| 140 unique_id_(g_save_package_id++), | 140 unique_id_(g_save_package_id++), |
| 141 wrote_to_completed_file_(false), | 141 wrote_to_completed_file_(false), |
| 142 wrote_to_failed_file_(false) { | 142 wrote_to_failed_file_(false) { |
| 143 DCHECK(page_url_.is_valid()); | 143 DCHECK(page_url_.is_valid()); |
| 144 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || | 144 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 145 save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML); | 145 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) || |
| 146 (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML)); | |
| 146 DCHECK(!saved_main_file_path_.empty() && | 147 DCHECK(!saved_main_file_path_.empty() && |
| 147 saved_main_file_path_.value().length() <= kMaxFilePathLength); | 148 saved_main_file_path_.value().length() <= kMaxFilePathLength); |
| 148 DCHECK(!saved_main_directory_path_.empty() && | 149 DCHECK(!saved_main_directory_path_.empty() && |
| 149 saved_main_directory_path_.value().length() < kMaxFilePathLength); | 150 saved_main_directory_path_.value().length() < kMaxFilePathLength); |
| 150 InternalInit(); | 151 InternalInit(); |
| 151 } | 152 } |
| 152 | 153 |
| 153 SavePackage::SavePackage(WebContents* web_contents) | 154 SavePackage::SavePackage(WebContents* web_contents) |
| 154 : content::WebContentsObserver(web_contents), | 155 : content::WebContentsObserver(web_contents), |
| 155 file_manager_(NULL), | 156 file_manager_(NULL), |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 wait_state_ = START_PROCESS; | 275 wait_state_ = START_PROCESS; |
| 275 | 276 |
| 276 // Initialize the request context and resource dispatcher. | 277 // Initialize the request context and resource dispatcher. |
| 277 content::BrowserContext* browser_context = | 278 content::BrowserContext* browser_context = |
| 278 web_contents()->GetBrowserContext(); | 279 web_contents()->GetBrowserContext(); |
| 279 if (!browser_context) { | 280 if (!browser_context) { |
| 280 NOTREACHED(); | 281 NOTREACHED(); |
| 281 return false; | 282 return false; |
| 282 } | 283 } |
| 283 | 284 |
| 285 if (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) { | |
| 286 // Force the extension to be mht. If the extension is left as html, then | |
| 287 // chrome will render it as html when opened instead of mhtml. | |
| 288 // Force the extension before creating the DownloadItem. | |
| 289 // TODO(benjhayden): Figure out how to move this back into the file picker. | |
| 290 // If the .html file already exists, then the user will be prompted to | |
| 291 // replace it, even thought it won't be replaced. If the .mht already | |
| 292 // exists, then the user will not be prompted to replace it, even though it | |
| 293 // will be replaced. The user will only be prompted to replace the .mht if | |
| 294 // they type out the filename including .mht. | |
| 295 saved_main_file_path_ = saved_main_file_path_.ReplaceExtension( | |
| 296 FILE_PATH_LITERAL("mht")); | |
| 297 } | |
| 298 | |
| 284 // The download manager keeps ownership but adds us as an observer. | 299 // The download manager keeps ownership but adds us as an observer. |
| 285 download_ = download_manager_->CreateSavePackageDownloadItem( | 300 download_ = download_manager_->CreateSavePackageDownloadItem( |
| 286 saved_main_file_path_, page_url_, | 301 saved_main_file_path_, page_url_, |
| 287 browser_context->IsOffTheRecord(), this); | 302 browser_context->IsOffTheRecord(), this); |
| 288 | 303 |
| 289 // Check save type and process the save page job. | 304 // Check save type and process the save page job. |
| 290 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { | 305 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { |
| 291 // Get directory | 306 // Get directory |
| 292 DCHECK(!saved_main_directory_path_.empty()); | 307 DCHECK(!saved_main_directory_path_.empty()); |
| 293 GetAllSavableResourceLinksForCurrentPage(); | 308 GetAllSavableResourceLinksForCurrentPage(); |
| 309 } else if (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) { | |
| 310 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind( | |
| 311 &SavePackage::MHTMLGenerated, this)); | |
| 294 } else { | 312 } else { |
| 295 wait_state_ = NET_FILES; | 313 wait_state_ = NET_FILES; |
| 296 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? | 314 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? |
| 297 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : | 315 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : |
| 298 SaveFileCreateInfo::SAVE_FILE_FROM_NET; | 316 SaveFileCreateInfo::SAVE_FILE_FROM_NET; |
| 299 SaveItem* save_item = new SaveItem(page_url_, | 317 SaveItem* save_item = new SaveItem(page_url_, |
| 300 GURL(), | 318 GURL(), |
| 301 this, | 319 this, |
| 302 save_source); | 320 save_source); |
| 303 // Add this item to waiting list. | 321 // Add this item to waiting list. |
| 304 waiting_item_queue_.push(save_item); | 322 waiting_item_queue_.push(save_item); |
| 305 all_save_items_count_ = 1; | 323 all_save_items_count_ = 1; |
| 306 download_->SetTotalBytes(1); | 324 download_->SetTotalBytes(1); |
| 307 | 325 |
| 308 DoSavingProcess(); | 326 DoSavingProcess(); |
| 309 } | 327 } |
| 310 | 328 |
| 311 return true; | 329 return true; |
| 312 } | 330 } |
| 313 | 331 |
| 332 void SavePackage::MHTMLGenerated(const FilePath& path, int64 size) { | |
| 333 if (size <= 0) { | |
| 334 Cancel(false); | |
| 335 } else { | |
| 336 download_->SetTotalBytes(size); | |
| 337 download_->OnAllDataSaved(size, DownloadItem::kEmptyFileHash); | |
| 338 download_->UpdateProgress(size, 0, ""); | |
| 339 wrote_to_completed_file_ = true; | |
| 340 Finish(); | |
| 341 } | |
| 342 } | |
| 343 | |
| 314 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further | 344 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further |
| 315 // restricted by NAME_MAX. The maximum allowed path looks like: | 345 // restricted by NAME_MAX. The maximum allowed path looks like: |
| 316 // '/path/to/save_dir' + '/' + NAME_MAX. | 346 // '/path/to/save_dir' + '/' + NAME_MAX. |
| 317 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) { | 347 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) { |
| 318 #if defined(OS_POSIX) | 348 #if defined(OS_POSIX) |
| 319 return std::min(kMaxFilePathLength, | 349 return std::min(kMaxFilePathLength, |
| 320 static_cast<uint32>(base_dir.value().length()) + | 350 static_cast<uint32>(base_dir.value().length()) + |
| 321 NAME_MAX + 1); | 351 NAME_MAX + 1); |
| 322 #else | 352 #else |
| 323 return kMaxFilePathLength; | 353 return kMaxFilePathLength; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 it != saved_failed_items_.end(); ++it) | 729 it != saved_failed_items_.end(); ++it) |
| 700 save_ids.push_back(it->second->save_id()); | 730 save_ids.push_back(it->second->save_id()); |
| 701 | 731 |
| 702 BrowserThread::PostTask( | 732 BrowserThread::PostTask( |
| 703 BrowserThread::FILE, FROM_HERE, | 733 BrowserThread::FILE, FROM_HERE, |
| 704 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, | 734 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, |
| 705 file_manager_, | 735 file_manager_, |
| 706 save_ids)); | 736 save_ids)); |
| 707 | 737 |
| 708 if (download_) { | 738 if (download_) { |
| 709 download_->OnAllDataSaved(all_save_items_count_, | 739 if (save_type_ != content::SAVE_PAGE_TYPE_AS_MHTML) { |
|
Randy Smith (Not in Mondays)
2012/04/16 17:45:47
I'm somewhat torn about this and related logic. I
benjhayden
2012/04/16 19:08:06
Done.
| |
| 710 DownloadItem::kEmptyFileHash); | 740 download_->OnAllDataSaved(all_save_items_count_, |
|
Randy Smith (Not in Mondays)
2012/04/16 17:45:47
nit: If there's an easy, not too ugly way to do it
benjhayden
2012/04/16 19:08:06
Done.
| |
| 741 DownloadItem::kEmptyFileHash); | |
| 742 } | |
| 711 download_->MarkAsComplete(); | 743 download_->MarkAsComplete(); |
| 712 FinalizeDownloadEntry(); | 744 FinalizeDownloadEntry(); |
| 713 } | 745 } |
| 714 } | 746 } |
| 715 | 747 |
| 716 // Called for updating end state. | 748 // Called for updating end state. |
| 717 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { | 749 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { |
| 718 // Because we might have canceled this saving job before, | 750 // Because we might have canceled this saving job before, |
| 719 // so we might not find corresponding SaveItem. Just ignore it. | 751 // so we might not find corresponding SaveItem. Just ignore it. |
| 720 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); | 752 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 | 800 |
| 769 save_item->Finish(0, false); | 801 save_item->Finish(0, false); |
| 770 | 802 |
| 771 PutInProgressItemToSavedMap(save_item); | 803 PutInProgressItemToSavedMap(save_item); |
| 772 | 804 |
| 773 // Inform the DownloadItem to update UI. | 805 // Inform the DownloadItem to update UI. |
| 774 // We use the received bytes as number of saved files. | 806 // We use the received bytes as number of saved files. |
| 775 if (download_) | 807 if (download_) |
| 776 download_->UpdateProgress(completed_count(), CurrentSpeed(), ""); | 808 download_->UpdateProgress(completed_count(), CurrentSpeed(), ""); |
| 777 | 809 |
| 778 if (save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || | 810 if ((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 779 save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { | 811 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) || |
| 812 (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)) { | |
| 780 // We got error when saving page. Treat it as disk error. | 813 // We got error when saving page. Treat it as disk error. |
| 781 Cancel(true); | 814 Cancel(true); |
| 782 } | 815 } |
| 783 | 816 |
| 784 if (canceled()) { | 817 if (canceled()) { |
| 785 DCHECK(finished_); | 818 DCHECK(finished_); |
| 786 return; | 819 return; |
| 787 } | 820 } |
| 788 | 821 |
| 789 // Continue processing the save page job. | 822 // Continue processing the save page job. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 875 wait_state_ = HTML_DATA; | 908 wait_state_ = HTML_DATA; |
| 876 // All non-HTML resources have been finished, start all remaining | 909 // All non-HTML resources have been finished, start all remaining |
| 877 // HTML files. | 910 // HTML files. |
| 878 SaveNextFile(true); | 911 SaveNextFile(true); |
| 879 } | 912 } |
| 880 } else if (in_process_count()) { | 913 } else if (in_process_count()) { |
| 881 // Continue asking for HTML data. | 914 // Continue asking for HTML data. |
| 882 DCHECK(wait_state_ == HTML_DATA); | 915 DCHECK(wait_state_ == HTML_DATA); |
| 883 } | 916 } |
| 884 } else { | 917 } else { |
| 885 // Save as HTML only. | 918 // Save as HTML only or MHTML. |
| 886 DCHECK(wait_state_ == NET_FILES); | 919 DCHECK(wait_state_ == NET_FILES); |
| 887 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML); | 920 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 921 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML)); | |
| 888 if (waiting_item_queue_.size()) { | 922 if (waiting_item_queue_.size()) { |
| 889 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); | 923 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); |
| 890 SaveNextFile(false); | 924 SaveNextFile(false); |
| 891 } | 925 } |
| 892 } | 926 } |
| 893 } | 927 } |
| 894 | 928 |
| 895 bool SavePackage::OnMessageReceived(const IPC::Message& message) { | 929 bool SavePackage::OnMessageReceived(const IPC::Message& message) { |
| 896 bool handled = true; | 930 bool handled = true; |
| 897 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) | 931 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1315 StopObservation(); | 1349 StopObservation(); |
| 1316 } | 1350 } |
| 1317 | 1351 |
| 1318 void SavePackage::FinalizeDownloadEntry() { | 1352 void SavePackage::FinalizeDownloadEntry() { |
| 1319 DCHECK(download_); | 1353 DCHECK(download_); |
| 1320 DCHECK(download_manager_); | 1354 DCHECK(download_manager_); |
| 1321 | 1355 |
| 1322 download_manager_->SavePageDownloadFinished(download_); | 1356 download_manager_->SavePageDownloadFinished(download_); |
| 1323 StopObservation(); | 1357 StopObservation(); |
| 1324 } | 1358 } |
| OLD | NEW |