| 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 : content::WebContentsObserver(web_contents), | 124 : content::WebContentsObserver(web_contents), |
| 125 file_manager_(NULL), | 125 file_manager_(NULL), |
| 126 download_manager_(NULL), | 126 download_manager_(NULL), |
| 127 download_(NULL), | 127 download_(NULL), |
| 128 page_url_(GetUrlToBeSaved()), | 128 page_url_(GetUrlToBeSaved()), |
| 129 saved_main_file_path_(file_full_path), | 129 saved_main_file_path_(file_full_path), |
| 130 saved_main_directory_path_(directory_full_path), | 130 saved_main_directory_path_(directory_full_path), |
| 131 title_(web_contents->GetTitle()), | 131 title_(web_contents->GetTitle()), |
| 132 start_tick_(base::TimeTicks::Now()), | 132 start_tick_(base::TimeTicks::Now()), |
| 133 finished_(false), | 133 finished_(false), |
| 134 mhtml_finishing_(false), |
| 134 user_canceled_(false), | 135 user_canceled_(false), |
| 135 disk_error_occurred_(false), | 136 disk_error_occurred_(false), |
| 136 save_type_(save_type), | 137 save_type_(save_type), |
| 137 all_save_items_count_(0), | 138 all_save_items_count_(0), |
| 138 wait_state_(INITIALIZE), | 139 wait_state_(INITIALIZE), |
| 139 contents_id_(web_contents->GetRenderProcessHost()->GetID()), | 140 contents_id_(web_contents->GetRenderProcessHost()->GetID()), |
| 140 unique_id_(g_save_package_id++), | 141 unique_id_(g_save_package_id++), |
| 141 wrote_to_completed_file_(false), | 142 wrote_to_completed_file_(false), |
| 142 wrote_to_failed_file_(false) { | 143 wrote_to_failed_file_(false) { |
| 143 DCHECK(page_url_.is_valid()); | 144 DCHECK(page_url_.is_valid()); |
| 144 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || | 145 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 145 save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML); | 146 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) || |
| 147 (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML)); |
| 146 DCHECK(!saved_main_file_path_.empty() && | 148 DCHECK(!saved_main_file_path_.empty() && |
| 147 saved_main_file_path_.value().length() <= kMaxFilePathLength); | 149 saved_main_file_path_.value().length() <= kMaxFilePathLength); |
| 148 DCHECK(!saved_main_directory_path_.empty() && | 150 DCHECK(!saved_main_directory_path_.empty() && |
| 149 saved_main_directory_path_.value().length() < kMaxFilePathLength); | 151 saved_main_directory_path_.value().length() < kMaxFilePathLength); |
| 150 InternalInit(); | 152 InternalInit(); |
| 151 } | 153 } |
| 152 | 154 |
| 153 SavePackage::SavePackage(WebContents* web_contents) | 155 SavePackage::SavePackage(WebContents* web_contents) |
| 154 : content::WebContentsObserver(web_contents), | 156 : content::WebContentsObserver(web_contents), |
| 155 file_manager_(NULL), | 157 file_manager_(NULL), |
| 156 download_manager_(NULL), | 158 download_manager_(NULL), |
| 157 download_(NULL), | 159 download_(NULL), |
| 158 page_url_(GetUrlToBeSaved()), | 160 page_url_(GetUrlToBeSaved()), |
| 159 title_(web_contents->GetTitle()), | 161 title_(web_contents->GetTitle()), |
| 160 start_tick_(base::TimeTicks::Now()), | 162 start_tick_(base::TimeTicks::Now()), |
| 161 finished_(false), | 163 finished_(false), |
| 164 mhtml_finishing_(false), |
| 162 user_canceled_(false), | 165 user_canceled_(false), |
| 163 disk_error_occurred_(false), | 166 disk_error_occurred_(false), |
| 164 save_type_(content::SAVE_PAGE_TYPE_UNKNOWN), | 167 save_type_(content::SAVE_PAGE_TYPE_UNKNOWN), |
| 165 all_save_items_count_(0), | 168 all_save_items_count_(0), |
| 166 wait_state_(INITIALIZE), | 169 wait_state_(INITIALIZE), |
| 167 contents_id_(web_contents->GetRenderProcessHost()->GetID()), | 170 contents_id_(web_contents->GetRenderProcessHost()->GetID()), |
| 168 unique_id_(g_save_package_id++), | 171 unique_id_(g_save_package_id++), |
| 169 wrote_to_completed_file_(false), | 172 wrote_to_completed_file_(false), |
| 170 wrote_to_failed_file_(false) { | 173 wrote_to_failed_file_(false) { |
| 171 DCHECK(page_url_.is_valid()); | 174 DCHECK(page_url_.is_valid()); |
| 172 InternalInit(); | 175 InternalInit(); |
| 173 } | 176 } |
| 174 | 177 |
| 175 // This is for testing use. Set |finished_| as true because we don't want | 178 // This is for testing use. Set |finished_| as true because we don't want |
| 176 // method Cancel to be be called in destructor in test mode. | 179 // method Cancel to be be called in destructor in test mode. |
| 177 // We also don't call InternalInit(). | 180 // We also don't call InternalInit(). |
| 178 SavePackage::SavePackage(WebContents* web_contents, | 181 SavePackage::SavePackage(WebContents* web_contents, |
| 179 const FilePath& file_full_path, | 182 const FilePath& file_full_path, |
| 180 const FilePath& directory_full_path) | 183 const FilePath& directory_full_path) |
| 181 : content::WebContentsObserver(web_contents), | 184 : content::WebContentsObserver(web_contents), |
| 182 file_manager_(NULL), | 185 file_manager_(NULL), |
| 183 download_manager_(NULL), | 186 download_manager_(NULL), |
| 184 download_(NULL), | 187 download_(NULL), |
| 185 saved_main_file_path_(file_full_path), | 188 saved_main_file_path_(file_full_path), |
| 186 saved_main_directory_path_(directory_full_path), | 189 saved_main_directory_path_(directory_full_path), |
| 187 start_tick_(base::TimeTicks::Now()), | 190 start_tick_(base::TimeTicks::Now()), |
| 188 finished_(true), | 191 finished_(true), |
| 192 mhtml_finishing_(false), |
| 189 user_canceled_(false), | 193 user_canceled_(false), |
| 190 disk_error_occurred_(false), | 194 disk_error_occurred_(false), |
| 191 save_type_(content::SAVE_PAGE_TYPE_UNKNOWN), | 195 save_type_(content::SAVE_PAGE_TYPE_UNKNOWN), |
| 192 all_save_items_count_(0), | 196 all_save_items_count_(0), |
| 193 wait_state_(INITIALIZE), | 197 wait_state_(INITIALIZE), |
| 194 contents_id_(0), | 198 contents_id_(0), |
| 195 unique_id_(g_save_package_id++), | 199 unique_id_(g_save_package_id++), |
| 196 wrote_to_completed_file_(false), | 200 wrote_to_completed_file_(false), |
| 197 wrote_to_failed_file_(false) { | 201 wrote_to_failed_file_(false) { |
| 198 } | 202 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 | 262 |
| 259 file_manager_ = rdh->save_file_manager(); | 263 file_manager_ = rdh->save_file_manager(); |
| 260 DCHECK(file_manager_); | 264 DCHECK(file_manager_); |
| 261 | 265 |
| 262 download_manager_ = web_contents()->GetBrowserContext()->GetDownloadManager(); | 266 download_manager_ = web_contents()->GetBrowserContext()->GetDownloadManager(); |
| 263 DCHECK(download_manager_); | 267 DCHECK(download_manager_); |
| 264 | 268 |
| 265 download_stats::RecordSavePackageEvent(download_stats::SAVE_PACKAGE_STARTED); | 269 download_stats::RecordSavePackageEvent(download_stats::SAVE_PACKAGE_STARTED); |
| 266 } | 270 } |
| 267 | 271 |
| 268 bool SavePackage::Init() { | 272 bool SavePackage::Init( |
| 273 const content::SavePackageDownloadCreatedCallback& |
| 274 download_created_callback) { |
| 269 // Set proper running state. | 275 // Set proper running state. |
| 270 if (wait_state_ != INITIALIZE) | 276 if (wait_state_ != INITIALIZE) |
| 271 return false; | 277 return false; |
| 272 | 278 |
| 273 wait_state_ = START_PROCESS; | 279 wait_state_ = START_PROCESS; |
| 274 | 280 |
| 275 // Initialize the request context and resource dispatcher. | 281 // Initialize the request context and resource dispatcher. |
| 276 content::BrowserContext* browser_context = | 282 content::BrowserContext* browser_context = |
| 277 web_contents()->GetBrowserContext(); | 283 web_contents()->GetBrowserContext(); |
| 278 if (!browser_context) { | 284 if (!browser_context) { |
| 279 NOTREACHED(); | 285 NOTREACHED(); |
| 280 return false; | 286 return false; |
| 281 } | 287 } |
| 282 | 288 |
| 283 // The download manager keeps ownership but adds us as an observer. | 289 // The download manager keeps ownership but adds us as an observer. |
| 284 download_ = download_manager_->CreateSavePackageDownloadItem( | 290 download_ = download_manager_->CreateSavePackageDownloadItem( |
| 285 saved_main_file_path_, page_url_, | 291 saved_main_file_path_, |
| 286 browser_context->IsOffTheRecord(), this); | 292 page_url_, |
| 293 browser_context->IsOffTheRecord(), |
| 294 ((save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) ? |
| 295 "multipart/related" : "text/html"), |
| 296 this); |
| 297 if (!download_created_callback.is_null()) |
| 298 download_created_callback.Run(download_); |
| 287 | 299 |
| 288 // Check save type and process the save page job. | 300 // Check save type and process the save page job. |
| 289 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { | 301 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { |
| 290 // Get directory | 302 // Get directory |
| 291 DCHECK(!saved_main_directory_path_.empty()); | 303 DCHECK(!saved_main_directory_path_.empty()); |
| 292 GetAllSavableResourceLinksForCurrentPage(); | 304 GetAllSavableResourceLinksForCurrentPage(); |
| 305 } else if (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) { |
| 306 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind( |
| 307 &SavePackage::OnMHTMLGenerated, this)); |
| 293 } else { | 308 } else { |
| 294 wait_state_ = NET_FILES; | 309 wait_state_ = NET_FILES; |
| 295 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? | 310 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? |
| 296 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : | 311 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : |
| 297 SaveFileCreateInfo::SAVE_FILE_FROM_NET; | 312 SaveFileCreateInfo::SAVE_FILE_FROM_NET; |
| 298 SaveItem* save_item = new SaveItem(page_url_, | 313 SaveItem* save_item = new SaveItem(page_url_, |
| 299 GURL(), | 314 GURL(), |
| 300 this, | 315 this, |
| 301 save_source); | 316 save_source); |
| 302 // Add this item to waiting list. | 317 // Add this item to waiting list. |
| 303 waiting_item_queue_.push(save_item); | 318 waiting_item_queue_.push(save_item); |
| 304 all_save_items_count_ = 1; | 319 all_save_items_count_ = 1; |
| 305 download_->SetTotalBytes(1); | 320 download_->SetTotalBytes(1); |
| 306 | 321 |
| 307 DoSavingProcess(); | 322 DoSavingProcess(); |
| 308 } | 323 } |
| 309 | 324 |
| 310 return true; | 325 return true; |
| 311 } | 326 } |
| 312 | 327 |
| 328 void SavePackage::OnMHTMLGenerated(const FilePath& path, int64 size) { |
| 329 if (size <= 0) { |
| 330 Cancel(false); |
| 331 return; |
| 332 } |
| 333 wrote_to_completed_file_ = true; |
| 334 download_->SetTotalBytes(size); |
| 335 download_->UpdateProgress(size, size, DownloadItem::kEmptyFileHash); |
| 336 // Must call OnAllDataSaved here in order for |
| 337 // GDataDownloadObserver::ShouldUpload() to return true. |
| 338 // ShouldCompleteDownload() may depend on the gdata uploader to finish. |
| 339 download_->OnAllDataSaved(size, DownloadItem::kEmptyFileHash); |
| 340 // GDataDownloadObserver is waiting for the upload to complete. When that |
| 341 // happens, it will call download_->MaybeCompleteDownload(), which will call |
| 342 // through our OnDownloadUpdated() allowing us to Finish(). |
| 343 // OnDownloadUpdated() may have been called in OnAllDataSaved(), so |this| may |
| 344 // be deleted at this point. |
| 345 } |
| 346 |
| 313 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further | 347 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further |
| 314 // restricted by NAME_MAX. The maximum allowed path looks like: | 348 // restricted by NAME_MAX. The maximum allowed path looks like: |
| 315 // '/path/to/save_dir' + '/' + NAME_MAX. | 349 // '/path/to/save_dir' + '/' + NAME_MAX. |
| 316 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) { | 350 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) { |
| 317 #if defined(OS_POSIX) | 351 #if defined(OS_POSIX) |
| 318 return std::min(kMaxFilePathLength, | 352 return std::min(kMaxFilePathLength, |
| 319 static_cast<uint32>(base_dir.value().length()) + | 353 static_cast<uint32>(base_dir.value().length()) + |
| 320 NAME_MAX + 1); | 354 NAME_MAX + 1); |
| 321 #else | 355 #else |
| 322 return kMaxFilePathLength; | 356 return kMaxFilePathLength; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 it != saved_failed_items_.end(); ++it) | 732 it != saved_failed_items_.end(); ++it) |
| 699 save_ids.push_back(it->second->save_id()); | 733 save_ids.push_back(it->second->save_id()); |
| 700 | 734 |
| 701 BrowserThread::PostTask( | 735 BrowserThread::PostTask( |
| 702 BrowserThread::FILE, FROM_HERE, | 736 BrowserThread::FILE, FROM_HERE, |
| 703 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, | 737 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, |
| 704 file_manager_, | 738 file_manager_, |
| 705 save_ids)); | 739 save_ids)); |
| 706 | 740 |
| 707 if (download_) { | 741 if (download_) { |
| 708 download_->OnAllDataSaved(all_save_items_count_, | 742 if (save_type_ != content::SAVE_PAGE_TYPE_AS_MHTML) |
| 709 DownloadItem::kEmptyFileHash); | 743 download_->OnAllDataSaved(all_save_items_count_, |
| 744 DownloadItem::kEmptyFileHash); |
| 710 download_->MarkAsComplete(); | 745 download_->MarkAsComplete(); |
| 711 FinalizeDownloadEntry(); | 746 FinalizeDownloadEntry(); |
| 712 } | 747 } |
| 713 } | 748 } |
| 714 | 749 |
| 715 // Called for updating end state. | 750 // Called for updating end state. |
| 716 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { | 751 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { |
| 717 // Because we might have canceled this saving job before, | 752 // Because we might have canceled this saving job before, |
| 718 // so we might not find corresponding SaveItem. Just ignore it. | 753 // so we might not find corresponding SaveItem. Just ignore it. |
| 719 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); | 754 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 | 802 |
| 768 save_item->Finish(0, false); | 803 save_item->Finish(0, false); |
| 769 | 804 |
| 770 PutInProgressItemToSavedMap(save_item); | 805 PutInProgressItemToSavedMap(save_item); |
| 771 | 806 |
| 772 // Inform the DownloadItem to update UI. | 807 // Inform the DownloadItem to update UI. |
| 773 // We use the received bytes as number of saved files. | 808 // We use the received bytes as number of saved files. |
| 774 if (download_) | 809 if (download_) |
| 775 download_->UpdateProgress(completed_count(), CurrentSpeed(), ""); | 810 download_->UpdateProgress(completed_count(), CurrentSpeed(), ""); |
| 776 | 811 |
| 777 if (save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || | 812 if ((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 778 save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { | 813 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) || |
| 814 (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)) { |
| 779 // We got error when saving page. Treat it as disk error. | 815 // We got error when saving page. Treat it as disk error. |
| 780 Cancel(true); | 816 Cancel(true); |
| 781 } | 817 } |
| 782 | 818 |
| 783 if (canceled()) { | 819 if (canceled()) { |
| 784 DCHECK(finished_); | 820 DCHECK(finished_); |
| 785 return; | 821 return; |
| 786 } | 822 } |
| 787 | 823 |
| 788 // Continue processing the save page job. | 824 // Continue processing the save page job. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 wait_state_ = HTML_DATA; | 910 wait_state_ = HTML_DATA; |
| 875 // All non-HTML resources have been finished, start all remaining | 911 // All non-HTML resources have been finished, start all remaining |
| 876 // HTML files. | 912 // HTML files. |
| 877 SaveNextFile(true); | 913 SaveNextFile(true); |
| 878 } | 914 } |
| 879 } else if (in_process_count()) { | 915 } else if (in_process_count()) { |
| 880 // Continue asking for HTML data. | 916 // Continue asking for HTML data. |
| 881 DCHECK(wait_state_ == HTML_DATA); | 917 DCHECK(wait_state_ == HTML_DATA); |
| 882 } | 918 } |
| 883 } else { | 919 } else { |
| 884 // Save as HTML only. | 920 // Save as HTML only or MHTML. |
| 885 DCHECK(wait_state_ == NET_FILES); | 921 DCHECK(wait_state_ == NET_FILES); |
| 886 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML); | 922 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) || |
| 923 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML)); |
| 887 if (waiting_item_queue_.size()) { | 924 if (waiting_item_queue_.size()) { |
| 888 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); | 925 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); |
| 889 SaveNextFile(false); | 926 SaveNextFile(false); |
| 890 } | 927 } |
| 891 } | 928 } |
| 892 } | 929 } |
| 893 | 930 |
| 894 bool SavePackage::OnMessageReceived(const IPC::Message& message) { | 931 bool SavePackage::OnMessageReceived(const IPC::Message& message) { |
| 895 bool handled = true; | 932 bool handled = true; |
| 896 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) | 933 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 // The WebContents which owns this SavePackage may have disappeared during | 1301 // The WebContents which owns this SavePackage may have disappeared during |
| 1265 // the UI->FILE->UI thread hop of | 1302 // the UI->FILE->UI thread hop of |
| 1266 // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo. | 1303 // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo. |
| 1267 if (!web_contents()) | 1304 if (!web_contents()) |
| 1268 return; | 1305 return; |
| 1269 | 1306 |
| 1270 FilePath::StringType default_extension; | 1307 FilePath::StringType default_extension; |
| 1271 if (can_save_as_complete) | 1308 if (can_save_as_complete) |
| 1272 default_extension = kDefaultHtmlExtension; | 1309 default_extension = kDefaultHtmlExtension; |
| 1273 | 1310 |
| 1274 // On ChromeOS, OnPathPicked is not invoked; SavePackageFilePickerChromeOS | |
| 1275 // handles the the save. | |
| 1276 download_manager_->delegate()->ChooseSavePath( | 1311 download_manager_->delegate()->ChooseSavePath( |
| 1277 web_contents(), suggested_path, default_extension, can_save_as_complete, | 1312 web_contents(), |
| 1313 suggested_path, |
| 1314 default_extension, |
| 1315 can_save_as_complete, |
| 1278 base::Bind(&SavePackage::OnPathPicked, AsWeakPtr())); | 1316 base::Bind(&SavePackage::OnPathPicked, AsWeakPtr())); |
| 1279 } | 1317 } |
| 1280 | 1318 |
| 1281 void SavePackage::OnPathPicked(const FilePath& final_name, | 1319 void SavePackage::OnPathPicked( |
| 1282 content::SavePageType type) { | 1320 const FilePath& final_name, |
| 1321 content::SavePageType type, |
| 1322 const content::SavePackageDownloadCreatedCallback& |
| 1323 download_created_callback) { |
| 1283 // Ensure the filename is safe. | 1324 // Ensure the filename is safe. |
| 1284 saved_main_file_path_ = final_name; | 1325 saved_main_file_path_ = final_name; |
| 1285 // TODO(asanka): This call may block on IO and shouldn't be made | 1326 // TODO(asanka): This call may block on IO and shouldn't be made |
| 1286 // from the UI thread. See http://crbug.com/61827. | 1327 // from the UI thread. See http://crbug.com/61827. |
| 1287 net::GenerateSafeFileName(web_contents()->GetContentsMimeType(), false, | 1328 net::GenerateSafeFileName(web_contents()->GetContentsMimeType(), false, |
| 1288 &saved_main_file_path_); | 1329 &saved_main_file_path_); |
| 1289 | 1330 |
| 1290 saved_main_directory_path_ = saved_main_file_path_.DirName(); | 1331 saved_main_directory_path_ = saved_main_file_path_.DirName(); |
| 1291 save_type_ = type; | 1332 save_type_ = type; |
| 1292 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { | 1333 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { |
| 1293 // Make new directory for saving complete file. | 1334 // Make new directory for saving complete file. |
| 1294 saved_main_directory_path_ = saved_main_directory_path_.Append( | 1335 saved_main_directory_path_ = saved_main_directory_path_.Append( |
| 1295 saved_main_file_path_.RemoveExtension().BaseName().value() + | 1336 saved_main_file_path_.RemoveExtension().BaseName().value() + |
| 1296 FILE_PATH_LITERAL("_files")); | 1337 FILE_PATH_LITERAL("_files")); |
| 1297 } | 1338 } |
| 1298 | 1339 |
| 1299 Init(); | 1340 Init(download_created_callback); |
| 1300 } | 1341 } |
| 1301 | 1342 |
| 1302 void SavePackage::StopObservation() { | 1343 void SavePackage::StopObservation() { |
| 1303 DCHECK(download_); | 1344 DCHECK(download_); |
| 1304 DCHECK(download_manager_); | 1345 DCHECK(download_manager_); |
| 1305 | 1346 |
| 1306 download_->RemoveObserver(this); | 1347 download_->RemoveObserver(this); |
| 1307 download_ = NULL; | 1348 download_ = NULL; |
| 1308 download_manager_ = NULL; | 1349 download_manager_ = NULL; |
| 1309 } | 1350 } |
| 1310 | 1351 |
| 1311 void SavePackage::OnDownloadUpdated(DownloadItem* download) { | 1352 void SavePackage::OnDownloadUpdated(DownloadItem* download) { |
| 1312 DCHECK(download_); | 1353 DCHECK(download_); |
| 1313 DCHECK(download_ == download); | 1354 DCHECK(download_ == download); |
| 1314 DCHECK(download_manager_); | 1355 DCHECK(download_manager_); |
| 1315 | 1356 |
| 1316 // Check for removal. | 1357 // Check for removal. |
| 1317 if (download->GetState() == DownloadItem::REMOVING) | 1358 if (download_->GetState() == DownloadItem::REMOVING) { |
| 1318 StopObservation(); | 1359 StopObservation(); |
| 1360 } |
| 1361 |
| 1362 // MHTML saves may need to wait for GData to finish uploading. |
| 1363 if ((save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) && |
| 1364 download_->AllDataSaved() && |
| 1365 !download_->IsComplete() && |
| 1366 !mhtml_finishing_ && |
| 1367 download_manager_->delegate()->ShouldCompleteDownload(download_)) { |
| 1368 // Post a task to avoid re-entering OnDownloadUpdated. Set a flag to |
| 1369 // prevent double-calling Finish() in case another OnDownloadUpdated happens |
| 1370 // before Finish() runs. |
| 1371 mhtml_finishing_ = true; |
| 1372 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 1373 base::Bind(&SavePackage::Finish, this)); |
| 1374 } |
| 1319 } | 1375 } |
| 1320 | 1376 |
| 1321 void SavePackage::FinalizeDownloadEntry() { | 1377 void SavePackage::FinalizeDownloadEntry() { |
| 1322 DCHECK(download_); | 1378 DCHECK(download_); |
| 1323 DCHECK(download_manager_); | 1379 DCHECK(download_manager_); |
| 1324 | 1380 |
| 1325 download_manager_->SavePageDownloadFinished(download_); | 1381 download_manager_->SavePageDownloadFinished(download_); |
| 1326 StopObservation(); | 1382 StopObservation(); |
| 1327 } | 1383 } |
| OLD | NEW |