Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1039)

Side by Side Diff: content/browser/download/save_package.cc

Issue 1529363006: Introducing SavePackageId and SaveItemId as distinct IdType<...>-based types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed CR feedback from Daniel. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/download/save_package.h ('k') | content/browser/download/save_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "net/base/io_buffer.h" 51 #include "net/base/io_buffer.h"
52 #include "net/base/mime_util.h" 52 #include "net/base/mime_util.h"
53 #include "net/url_request/url_request_context.h" 53 #include "net/url_request/url_request_context.h"
54 #include "url/url_constants.h" 54 #include "url/url_constants.h"
55 55
56 using base::Time; 56 using base::Time;
57 57
58 namespace content { 58 namespace content {
59 namespace { 59 namespace {
60 60
61 // A counter for uniquely identifying each save package. 61 // Generates unique ids for SavePackage::unique_id_ field.
62 int g_save_package_id = 0; 62 SavePackageId GetNextSavePackageId() {
63 static int g_save_package_id = 0;
64 return SavePackageId::FromUnsafeValue(g_save_package_id++);
65 }
63 66
64 // Default name which will be used when we can not get proper name from 67 // Default name which will be used when we can not get proper name from
65 // resource URL. 68 // resource URL.
66 const char kDefaultSaveName[] = "saved_resource"; 69 const char kDefaultSaveName[] = "saved_resource";
67 70
68 // Maximum number of file ordinal number. I think it's big enough for resolving 71 // Maximum number of file ordinal number. I think it's big enough for resolving
69 // name-conflict files which has same base file name. 72 // name-conflict files which has same base file name.
70 const int32_t kMaxFileOrdinalNumber = 9999; 73 const int32_t kMaxFileOrdinalNumber = 9999;
71 74
72 // Maximum length for file path. Since Windows have MAX_PATH limitation for 75 // Maximum length for file path. Since Windows have MAX_PATH limitation for
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 title_(web_contents->GetTitle()), 158 title_(web_contents->GetTitle()),
156 start_tick_(base::TimeTicks::Now()), 159 start_tick_(base::TimeTicks::Now()),
157 finished_(false), 160 finished_(false),
158 mhtml_finishing_(false), 161 mhtml_finishing_(false),
159 user_canceled_(false), 162 user_canceled_(false),
160 disk_error_occurred_(false), 163 disk_error_occurred_(false),
161 save_type_(save_type), 164 save_type_(save_type),
162 all_save_items_count_(0), 165 all_save_items_count_(0),
163 file_name_set_(&base::FilePath::CompareLessIgnoreCase), 166 file_name_set_(&base::FilePath::CompareLessIgnoreCase),
164 wait_state_(INITIALIZE), 167 wait_state_(INITIALIZE),
165 unique_id_(g_save_package_id++), 168 unique_id_(GetNextSavePackageId()),
166 wrote_to_completed_file_(false), 169 wrote_to_completed_file_(false),
167 wrote_to_failed_file_(false) { 170 wrote_to_failed_file_(false) {
168 DCHECK(page_url_.is_valid()); 171 DCHECK(page_url_.is_valid());
169 DCHECK((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) || 172 DCHECK((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
170 (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) || 173 (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ||
171 (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML)) 174 (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML))
172 << save_type_; 175 << save_type_;
173 DCHECK(!saved_main_file_path_.empty() && 176 DCHECK(!saved_main_file_path_.empty() &&
174 saved_main_file_path_.value().length() <= kMaxFilePathLength); 177 saved_main_file_path_.value().length() <= kMaxFilePathLength);
175 DCHECK(!saved_main_directory_path_.empty() && 178 DCHECK(!saved_main_directory_path_.empty() &&
(...skipping 11 matching lines...) Expand all
187 title_(web_contents->GetTitle()), 190 title_(web_contents->GetTitle()),
188 start_tick_(base::TimeTicks::Now()), 191 start_tick_(base::TimeTicks::Now()),
189 finished_(false), 192 finished_(false),
190 mhtml_finishing_(false), 193 mhtml_finishing_(false),
191 user_canceled_(false), 194 user_canceled_(false),
192 disk_error_occurred_(false), 195 disk_error_occurred_(false),
193 save_type_(SAVE_PAGE_TYPE_UNKNOWN), 196 save_type_(SAVE_PAGE_TYPE_UNKNOWN),
194 all_save_items_count_(0), 197 all_save_items_count_(0),
195 file_name_set_(&base::FilePath::CompareLessIgnoreCase), 198 file_name_set_(&base::FilePath::CompareLessIgnoreCase),
196 wait_state_(INITIALIZE), 199 wait_state_(INITIALIZE),
197 unique_id_(g_save_package_id++), 200 unique_id_(GetNextSavePackageId()),
198 wrote_to_completed_file_(false), 201 wrote_to_completed_file_(false),
199 wrote_to_failed_file_(false) { 202 wrote_to_failed_file_(false) {
200 DCHECK(page_url_.is_valid()); 203 DCHECK(page_url_.is_valid());
201 InternalInit(); 204 InternalInit();
202 } 205 }
203 206
204 // This is for testing use. Set |finished_| as true because we don't want 207 // This is for testing use. Set |finished_| as true because we don't want
205 // method Cancel to be be called in destructor in test mode. 208 // method Cancel to be be called in destructor in test mode.
206 // We also don't call InternalInit(). 209 // We also don't call InternalInit().
207 SavePackage::SavePackage(WebContents* web_contents, 210 SavePackage::SavePackage(WebContents* web_contents,
208 const base::FilePath& file_full_path, 211 const base::FilePath& file_full_path,
209 const base::FilePath& directory_full_path) 212 const base::FilePath& directory_full_path)
210 : WebContentsObserver(web_contents), 213 : WebContentsObserver(web_contents),
211 number_of_frames_pending_response_(0), 214 number_of_frames_pending_response_(0),
212 file_manager_(NULL), 215 file_manager_(NULL),
213 download_manager_(NULL), 216 download_manager_(NULL),
214 download_(NULL), 217 download_(NULL),
215 saved_main_file_path_(file_full_path), 218 saved_main_file_path_(file_full_path),
216 saved_main_directory_path_(directory_full_path), 219 saved_main_directory_path_(directory_full_path),
217 start_tick_(base::TimeTicks::Now()), 220 start_tick_(base::TimeTicks::Now()),
218 finished_(true), 221 finished_(true),
219 mhtml_finishing_(false), 222 mhtml_finishing_(false),
220 user_canceled_(false), 223 user_canceled_(false),
221 disk_error_occurred_(false), 224 disk_error_occurred_(false),
222 save_type_(SAVE_PAGE_TYPE_UNKNOWN), 225 save_type_(SAVE_PAGE_TYPE_UNKNOWN),
223 all_save_items_count_(0), 226 all_save_items_count_(0),
224 file_name_set_(&base::FilePath::CompareLessIgnoreCase), 227 file_name_set_(&base::FilePath::CompareLessIgnoreCase),
225 wait_state_(INITIALIZE), 228 wait_state_(INITIALIZE),
226 unique_id_(g_save_package_id++), 229 unique_id_(GetNextSavePackageId()),
227 wrote_to_completed_file_(false), 230 wrote_to_completed_file_(false),
228 wrote_to_failed_file_(false) {} 231 wrote_to_failed_file_(false) {}
229 232
230 SavePackage::~SavePackage() { 233 SavePackage::~SavePackage() {
231 // Stop receiving saving job's updates 234 // Stop receiving saving job's updates
232 if (!finished_ && !canceled()) { 235 if (!finished_ && !canceled()) {
233 // Unexpected quit. 236 // Unexpected quit.
234 Cancel(true); 237 Cancel(true);
235 } 238 }
236 239
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 623
621 // Check whether we begin to require serialized HTML data. 624 // Check whether we begin to require serialized HTML data.
622 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML && 625 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML &&
623 wait_state_ == HTML_DATA) { 626 wait_state_ == HTML_DATA) {
624 // Inform backend to serialize the all frames' DOM and send serialized 627 // Inform backend to serialize the all frames' DOM and send serialized
625 // HTML data back. 628 // HTML data back.
626 GetSerializedHtmlWithLocalLinks(); 629 GetSerializedHtmlWithLocalLinks();
627 } 630 }
628 } 631 }
629 632
630 SaveItem* SavePackage::LookupSaveItemInProcess(int32_t save_item_id) { 633 SaveItem* SavePackage::LookupSaveItemInProcess(SaveItemId save_item_id) {
631 auto it = in_progress_items_.find(save_item_id); 634 auto it = in_progress_items_.find(save_item_id);
632 if (it != in_progress_items_.end()) { 635 if (it != in_progress_items_.end()) {
633 SaveItem* save_item = it->second; 636 SaveItem* save_item = it->second;
634 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state()); 637 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state());
635 return save_item; 638 return save_item;
636 } 639 }
637 return nullptr; 640 return nullptr;
638 } 641 }
639 642
640 void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) { 643 void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) {
641 SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id()); 644 SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id());
642 DCHECK(it != in_progress_items_.end()); 645 DCHECK(it != in_progress_items_.end());
643 DCHECK(save_item == it->second); 646 DCHECK(save_item == it->second);
644 in_progress_items_.erase(it); 647 in_progress_items_.erase(it);
645 648
646 if (save_item->success()) { 649 if (save_item->success()) {
647 // Add it to saved_success_items_. 650 // Add it to saved_success_items_.
648 DCHECK(saved_success_items_.find(save_item->id()) == 651 DCHECK(saved_success_items_.find(save_item->id()) ==
649 saved_success_items_.end()); 652 saved_success_items_.end());
650 saved_success_items_[save_item->id()] = save_item; 653 saved_success_items_[save_item->id()] = save_item;
651 } else { 654 } else {
652 // Add it to saved_failed_items_. 655 // Add it to saved_failed_items_.
653 DCHECK(saved_failed_items_.find(save_item->id()) == 656 DCHECK(saved_failed_items_.find(save_item->id()) ==
654 saved_failed_items_.end()); 657 saved_failed_items_.end());
655 saved_failed_items_[save_item->id()] = save_item; 658 saved_failed_items_[save_item->id()] = save_item;
656 } 659 }
657 } 660 }
658 661
659 // Called for updating saving state. 662 // Called for updating saving state.
660 bool SavePackage::UpdateSaveProgress(int32_t save_item_id, 663 bool SavePackage::UpdateSaveProgress(SaveItemId save_item_id,
661 int64_t size, 664 int64_t size,
662 bool write_success) { 665 bool write_success) {
663 // Because we might have canceled this saving job before, 666 // Because we might have canceled this saving job before,
664 // so we might not find corresponding SaveItem. 667 // so we might not find corresponding SaveItem.
665 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); 668 SaveItem* save_item = LookupSaveItemInProcess(save_item_id);
666 if (!save_item) 669 if (!save_item)
667 return false; 670 return false;
668 671
669 save_item->Update(size); 672 save_item->Update(size);
670 673
671 // If we got disk error, cancel whole save page job. 674 // If we got disk error, cancel whole save page job.
672 if (!write_success) { 675 if (!write_success) {
673 // Cancel job with reason of disk error. 676 // Cancel job with reason of disk error.
674 Cancel(false); 677 Cancel(false);
675 } 678 }
676 return true; 679 return true;
677 } 680 }
678 681
679 // Stop all page saving jobs that are in progress and instruct the file thread 682 // Stop all page saving jobs that are in progress and instruct the file thread
680 // to delete all saved files. 683 // to delete all saved files.
681 void SavePackage::Stop() { 684 void SavePackage::Stop() {
682 // If we haven't moved out of the initial state, there's nothing to cancel and 685 // If we haven't moved out of the initial state, there's nothing to cancel and
683 // there won't be valid pointers for file_manager_ or download_. 686 // there won't be valid pointers for file_manager_ or download_.
684 if (wait_state_ == INITIALIZE) 687 if (wait_state_ == INITIALIZE)
685 return; 688 return;
686 689
687 // When stopping, if it still has some items in in_progress, cancel them. 690 // When stopping, if it still has some items in in_progress, cancel them.
688 DCHECK(canceled()); 691 DCHECK(canceled());
689 if (in_process_count()) { 692 if (in_process_count()) {
690 SaveItemIdMap::iterator it = in_progress_items_.begin(); 693 for (const auto& it : in_progress_items_) {
691 for (; it != in_progress_items_.end(); ++it) { 694 SaveItem* save_item = it.second;
692 SaveItem* save_item = it->second;
693 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state()); 695 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state());
694 save_item->Cancel(); 696 save_item->Cancel();
695 } 697 }
696 // Remove all in progress item to saved map. For failed items, they will 698 // Remove all in progress item to saved map. For failed items, they will
697 // be put into saved_failed_items_, for successful item, they will be put 699 // be put into saved_failed_items_, for successful item, they will be put
698 // into saved_success_items_. 700 // into saved_success_items_.
699 while (in_process_count()) 701 while (in_process_count())
700 PutInProgressItemToSavedMap(in_progress_items_.begin()->second); 702 PutInProgressItemToSavedMap(in_progress_items_.begin()->second);
701 } 703 }
702 704
703 // This vector contains the save ids of the save files which SaveFileManager 705 // This vector contains the save ids of the save files which SaveFileManager
704 // needs to remove from its save_file_map_. 706 // needs to remove from its save_file_map_.
705 std::vector<int> save_item_ids; 707 std::vector<SaveItemId> save_item_ids;
706 for (const auto& it : saved_success_items_) 708 for (const auto& it : saved_success_items_)
707 save_item_ids.push_back(it.first); 709 save_item_ids.push_back(it.first);
708 for (const auto& it : saved_failed_items_) 710 for (const auto& it : saved_failed_items_)
709 save_item_ids.push_back(it.first); 711 save_item_ids.push_back(it.first);
710 712
711 BrowserThread::PostTask( 713 BrowserThread::PostTask(
712 BrowserThread::FILE, FROM_HERE, 714 BrowserThread::FILE, FROM_HERE,
713 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_, 715 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_,
714 save_item_ids)); 716 save_item_ids));
715 717
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 762
761 // Record any errors that occurred. 763 // Record any errors that occurred.
762 if (wrote_to_completed_file_) 764 if (wrote_to_completed_file_)
763 RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_COMPLETED); 765 RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_COMPLETED);
764 766
765 if (wrote_to_failed_file_) 767 if (wrote_to_failed_file_)
766 RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_FAILED); 768 RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_FAILED);
767 769
768 // This vector contains the save ids of the save files which SaveFileManager 770 // This vector contains the save ids of the save files which SaveFileManager
769 // needs to remove from its save_file_map_. 771 // needs to remove from its save_file_map_.
770 std::vector<int> list_of_failed_save_item_ids; 772 std::vector<SaveItemId> list_of_failed_save_item_ids;
771 for (const auto& it : saved_failed_items_) { 773 for (const auto& it : saved_failed_items_) {
772 SaveItem* save_item = it.second; 774 SaveItem* save_item = it.second;
773 DCHECK_EQ(it.first, save_item->id()); 775 DCHECK_EQ(it.first, save_item->id());
774 list_of_failed_save_item_ids.push_back(save_item->id()); 776 list_of_failed_save_item_ids.push_back(save_item->id());
775 } 777 }
776 778
777 BrowserThread::PostTask( 779 BrowserThread::PostTask(
778 BrowserThread::FILE, FROM_HERE, 780 BrowserThread::FILE, FROM_HERE,
779 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_, 781 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_,
780 list_of_failed_save_item_ids)); 782 list_of_failed_save_item_ids));
781 783
782 if (download_) { 784 if (download_) {
783 // Hack to avoid touching download_ after user cancel. 785 // Hack to avoid touching download_ after user cancel.
784 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem 786 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem
785 // with SavePackage flow. 787 // with SavePackage flow.
786 if (download_->GetState() == DownloadItem::IN_PROGRESS) { 788 if (download_->GetState() == DownloadItem::IN_PROGRESS) {
787 if (save_type_ != SAVE_PAGE_TYPE_AS_MHTML) { 789 if (save_type_ != SAVE_PAGE_TYPE_AS_MHTML) {
788 download_->DestinationUpdate( 790 download_->DestinationUpdate(
789 all_save_items_count_, CurrentSpeed(), std::string()); 791 all_save_items_count_, CurrentSpeed(), std::string());
790 download_->OnAllDataSaved(DownloadItem::kEmptyFileHash); 792 download_->OnAllDataSaved(DownloadItem::kEmptyFileHash);
791 } 793 }
792 download_->MarkAsComplete(); 794 download_->MarkAsComplete();
793 } 795 }
794 FinalizeDownloadEntry(); 796 FinalizeDownloadEntry();
795 } 797 }
796 } 798 }
797 799
798 // Called for updating end state. 800 // Called for updating end state.
799 void SavePackage::SaveFinished(int32_t save_item_id, 801 void SavePackage::SaveFinished(SaveItemId save_item_id,
800 int64_t size, 802 int64_t size,
801 bool is_success) { 803 bool is_success) {
802 // Because we might have canceled this saving job before, 804 // Because we might have canceled this saving job before,
803 // so we might not find corresponding SaveItem. Just ignore it. 805 // so we might not find corresponding SaveItem. Just ignore it.
804 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); 806 SaveItem* save_item = LookupSaveItemInProcess(save_item_id);
805 if (!save_item) 807 if (!save_item)
806 return; 808 return;
807 809
808 // Let SaveItem set end state. 810 // Let SaveItem set end state.
809 save_item->Finish(size, is_success); 811 save_item->Finish(size, is_success);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 if (it == frame_tree_node_id_to_save_item_.end()) { 1039 if (it == frame_tree_node_id_to_save_item_.end()) {
1038 // Sanitization of renderer IPC - we will have no save item only if 1040 // Sanitization of renderer IPC - we will have no save item only if
1039 // the renderer misbehaves and sends OnSerializedHtmlFragment IPC without 1041 // the renderer misbehaves and sends OnSerializedHtmlFragment IPC without
1040 // being asked to. 1042 // being asked to.
1041 NOTREACHED(); 1043 NOTREACHED();
1042 return; 1044 return;
1043 } 1045 }
1044 SaveItem* save_item = it->second; 1046 SaveItem* save_item = it->second;
1045 DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source()); 1047 DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source());
1046 if (save_item->state() != SaveItem::IN_PROGRESS) { 1048 if (save_item->state() != SaveItem::IN_PROGRESS) {
1047 for (SavedItemMap::iterator saved_it = saved_success_items_.begin(); 1049 for (const auto& saved_it : saved_success_items_) {
1048 saved_it != saved_success_items_.end(); ++saved_it) { 1050 if (saved_it.second->url() == save_item->url()) {
1049 if (saved_it->second->url() == save_item->url()) {
1050 wrote_to_completed_file_ = true; 1051 wrote_to_completed_file_ = true;
1051 break; 1052 break;
1052 } 1053 }
1053 } 1054 }
1054 1055
1055 auto it2 = saved_failed_items_.find(save_item->id()); 1056 auto it2 = saved_failed_items_.find(save_item->id());
1056 if (it2 != saved_failed_items_.end()) 1057 if (it2 != saved_failed_items_.end())
1057 wrote_to_failed_file_ = true; 1058 wrote_to_failed_file_ = true;
1058 1059
1059 return; 1060 return;
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 1495
1495 void SavePackage::FinalizeDownloadEntry() { 1496 void SavePackage::FinalizeDownloadEntry() {
1496 DCHECK(download_); 1497 DCHECK(download_);
1497 DCHECK(download_manager_); 1498 DCHECK(download_manager_);
1498 1499
1499 download_manager_->OnSavePackageSuccessfullyFinished(download_); 1500 download_manager_->OnSavePackageSuccessfullyFinished(download_);
1500 StopObservation(); 1501 StopObservation();
1501 } 1502 }
1502 1503
1503 } // namespace content 1504 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/save_package.h ('k') | content/browser/download/save_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698