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

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

Issue 7277073: Support for adding save page download items into downloads history. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/i18n/file_util_icu.h" 11 #include "base/i18n/file_util_icu.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/string_piece.h" 15 #include "base/string_piece.h"
16 #include "base/string_split.h" 16 #include "base/string_split.h"
17 #include "base/sys_string_conversions.h" 17 #include "base/sys_string_conversions.h"
18 #include "base/task.h" 18 #include "base/task.h"
19 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "chrome/browser/download/download_history.h"
21 #include "chrome/browser/download/download_item.h" 22 #include "chrome/browser/download/download_item.h"
22 #include "chrome/browser/download/download_item_model.h" 23 #include "chrome/browser/download/download_item_model.h"
23 #include "chrome/browser/download/download_manager.h" 24 #include "chrome/browser/download/download_manager.h"
24 #include "chrome/browser/download/download_util.h" 25 #include "chrome/browser/download/download_util.h"
25 #include "chrome/browser/prefs/pref_member.h" 26 #include "chrome/browser/prefs/pref_member.h"
26 #include "chrome/browser/prefs/pref_service.h" 27 #include "chrome/browser/prefs/pref_service.h"
27 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/common/pref_names.h" 29 #include "chrome/common/pref_names.h"
29 #include "content/browser/browser_thread.h" 30 #include "content/browser/browser_thread.h"
30 #include "content/browser/content_browser_client.h" 31 #include "content/browser/content_browser_client.h"
(...skipping 13 matching lines...) Expand all
44 #include "net/base/mime_util.h" 45 #include "net/base/mime_util.h"
45 #include "net/base/net_util.h" 46 #include "net/base/net_util.h"
46 #include "net/url_request/url_request_context.h" 47 #include "net/url_request/url_request_context.h"
47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializerClie nt.h" 48 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializerClie nt.h"
48 49
49 using base::Time; 50 using base::Time;
50 using WebKit::WebPageSerializerClient; 51 using WebKit::WebPageSerializerClient;
51 52
52 namespace { 53 namespace {
53 54
55 /*
56 Race analysis:
Paweł Hajdan Jr. 2011/07/27 16:53:51 I'm not sure about adding this as a comment in the
Randy Smith (Not in Mondays) 2011/07/27 21:08:35 Yeah. Another take on this is that if we need thi
achuithb 2011/07/28 00:45:58 I've moved the comments to the end of download_man
57 + The actions that can race against each other are:
58 * History callback
59 * Completion (save page as finishes)
60 * Cancel (SavePackage::Stop())
61 * Shutdown
62 * Remove
63 + Cancel and completion can be considered equivalent for race
64 processing, as they have the same effect on the download manager, and
65 SavePackage won't produce any more events after either of them. I'll
66 refer to the OR of these two events as "Finishing".
67 + Anything that occurs after both History callback and Finishing is
68 uninteresting, as there won't be anything in the queues anymore.
69 + Only the History Callback or Remove can occur after Shutdown (the
70 SavePackage system won't produce any more events after these two).
71 + Remove does not cancel (probably not a mistake you'd make, but it
72 does on downloads, so I'm noting it for myself).
73 + Shutdown can only occur after Finishing(Cancel) (destroying a
74 profile happens strictly after destroying all TabContents associated
75 with the profile).
76 + Remove can only occur after the History Callback.
77
78 This leads to the following possible orders of events:
79 -- Finishing, History Callback
80 Variations on the basic one. Ok.
81 -- Finishing(Cancel), Shutdown, History Callback
82 The cancel leaves the DI in the queue, shutdown removes and deletes
83 it, and the history callback doesn't find it, leaving it in the DB
84 as IN_PROGRESS, which will be turned into Cancelled on next load.
85 Ok.
86 -- History Callback, Finishing
87 The basic order. Ok.
88 -- History Callback, Remove, Finishing
89 This results in a lack of update of the database to indicate
90 that the download has completed (if the finishing action is
91 completed), but that's not solvable until we cancel on Remove
92 (which would update the DB).
93 */
94
54 // A counter for uniquely identifying each save package. 95 // A counter for uniquely identifying each save package.
55 int g_save_package_id = 0; 96 int g_save_package_id = 0;
56 97
57 // Default name which will be used when we can not get proper name from 98 // Default name which will be used when we can not get proper name from
58 // resource URL. 99 // resource URL.
59 const char kDefaultSaveName[] = "saved_resource"; 100 const char kDefaultSaveName[] = "saved_resource";
60 101
61 // Maximum number of file ordinal number. I think it's big enough for resolving 102 // Maximum number of file ordinal number. I think it's big enough for resolving
62 // name-conflict files which has same base file name. 103 // name-conflict files which has same base file name.
63 const int32 kMaxFileOrdinalNumber = 9999; 104 const int32 kMaxFileOrdinalNumber = 9999;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 #else 154 #else
114 FILE_PATH_LITERAL("html"); 155 FILE_PATH_LITERAL("html");
115 #endif 156 #endif
116 157
117 SavePackage::SavePackage(TabContents* tab_contents, 158 SavePackage::SavePackage(TabContents* tab_contents,
118 SavePackageType save_type, 159 SavePackageType save_type,
119 const FilePath& file_full_path, 160 const FilePath& file_full_path,
120 const FilePath& directory_full_path) 161 const FilePath& directory_full_path)
121 : TabContentsObserver(tab_contents), 162 : TabContentsObserver(tab_contents),
122 file_manager_(NULL), 163 file_manager_(NULL),
164 download_manager_(NULL),
123 download_(NULL), 165 download_(NULL),
124 page_url_(GetUrlToBeSaved()), 166 page_url_(GetUrlToBeSaved()),
125 saved_main_file_path_(file_full_path), 167 saved_main_file_path_(file_full_path),
126 saved_main_directory_path_(directory_full_path), 168 saved_main_directory_path_(directory_full_path),
127 title_(tab_contents->GetTitle()), 169 title_(tab_contents->GetTitle()),
128 finished_(false), 170 finished_(false),
129 user_canceled_(false), 171 user_canceled_(false),
130 disk_error_occurred_(false), 172 disk_error_occurred_(false),
131 save_type_(save_type), 173 save_type_(save_type),
132 all_save_items_count_(0), 174 all_save_items_count_(0),
133 wait_state_(INITIALIZE), 175 wait_state_(INITIALIZE),
134 tab_id_(tab_contents->GetRenderProcessHost()->id()), 176 tab_id_(tab_contents->GetRenderProcessHost()->id()),
135 unique_id_(g_save_package_id++), 177 unique_id_(g_save_package_id++),
136 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 178 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
137 DCHECK(page_url_.is_valid()); 179 DCHECK(page_url_.is_valid());
138 DCHECK(save_type_ == SAVE_AS_ONLY_HTML || 180 DCHECK(save_type_ == SAVE_AS_ONLY_HTML ||
139 save_type_ == SAVE_AS_COMPLETE_HTML); 181 save_type_ == SAVE_AS_COMPLETE_HTML);
140 DCHECK(!saved_main_file_path_.empty() && 182 DCHECK(!saved_main_file_path_.empty() &&
141 saved_main_file_path_.value().length() <= kMaxFilePathLength); 183 saved_main_file_path_.value().length() <= kMaxFilePathLength);
142 DCHECK(!saved_main_directory_path_.empty() && 184 DCHECK(!saved_main_directory_path_.empty() &&
143 saved_main_directory_path_.value().length() < kMaxFilePathLength); 185 saved_main_directory_path_.value().length() < kMaxFilePathLength);
144 InternalInit(); 186 InternalInit();
145 } 187 }
146 188
147 SavePackage::SavePackage(TabContents* tab_contents) 189 SavePackage::SavePackage(TabContents* tab_contents)
148 : TabContentsObserver(tab_contents), 190 : TabContentsObserver(tab_contents),
149 file_manager_(NULL), 191 file_manager_(NULL),
192 download_manager_(NULL),
150 download_(NULL), 193 download_(NULL),
151 page_url_(GetUrlToBeSaved()), 194 page_url_(GetUrlToBeSaved()),
152 title_(tab_contents->GetTitle()), 195 title_(tab_contents->GetTitle()),
153 finished_(false), 196 finished_(false),
154 user_canceled_(false), 197 user_canceled_(false),
155 disk_error_occurred_(false), 198 disk_error_occurred_(false),
156 save_type_(SAVE_TYPE_UNKNOWN), 199 save_type_(SAVE_TYPE_UNKNOWN),
157 all_save_items_count_(0), 200 all_save_items_count_(0),
158 wait_state_(INITIALIZE), 201 wait_state_(INITIALIZE),
159 tab_id_(tab_contents->GetRenderProcessHost()->id()), 202 tab_id_(tab_contents->GetRenderProcessHost()->id()),
160 unique_id_(g_save_package_id++), 203 unique_id_(g_save_package_id++),
161 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 204 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
162 DCHECK(page_url_.is_valid()); 205 DCHECK(page_url_.is_valid());
163 InternalInit(); 206 InternalInit();
164 } 207 }
165 208
166 // This is for testing use. Set |finished_| as true because we don't want 209 // This is for testing use. Set |finished_| as true because we don't want
167 // method Cancel to be be called in destructor in test mode. 210 // method Cancel to be be called in destructor in test mode.
168 // We also don't call InternalInit(). 211 // We also don't call InternalInit().
169 SavePackage::SavePackage(TabContents* tab_contents, 212 SavePackage::SavePackage(TabContents* tab_contents,
170 const FilePath& file_full_path, 213 const FilePath& file_full_path,
171 const FilePath& directory_full_path) 214 const FilePath& directory_full_path)
172 : TabContentsObserver(tab_contents), 215 : TabContentsObserver(tab_contents),
173 file_manager_(NULL), 216 file_manager_(NULL),
217 download_manager_(NULL),
174 download_(NULL), 218 download_(NULL),
175 saved_main_file_path_(file_full_path), 219 saved_main_file_path_(file_full_path),
176 saved_main_directory_path_(directory_full_path), 220 saved_main_directory_path_(directory_full_path),
177 finished_(true), 221 finished_(true),
178 user_canceled_(false), 222 user_canceled_(false),
179 disk_error_occurred_(false), 223 disk_error_occurred_(false),
180 save_type_(SAVE_TYPE_UNKNOWN), 224 save_type_(SAVE_TYPE_UNKNOWN),
181 all_save_items_count_(0), 225 all_save_items_count_(0),
182 wait_state_(INITIALIZE), 226 wait_state_(INITIALIZE),
183 tab_id_(0), 227 tab_id_(0),
184 unique_id_(g_save_package_id++), 228 unique_id_(g_save_package_id++),
185 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 229 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
186 } 230 }
187 231
188 SavePackage::~SavePackage() { 232 SavePackage::~SavePackage() {
189 // Stop receiving saving job's updates 233 // Stop receiving saving job's updates
190 if (!finished_ && !canceled()) { 234 if (!finished_ && !canceled()) {
191 // Unexpected quit. 235 // Unexpected quit.
192 Cancel(true); 236 Cancel(true);
193 } 237 }
194 238
239 // We should no longer be observing the DownloadManager at this point.
240 CHECK(!download_manager_);
241 CHECK(!download_);
242
195 DCHECK(all_save_items_count_ == (waiting_item_queue_.size() + 243 DCHECK(all_save_items_count_ == (waiting_item_queue_.size() +
196 completed_count() + 244 completed_count() +
197 in_process_count())); 245 in_process_count()));
198 // Free all SaveItems. 246 // Free all SaveItems.
199 while (!waiting_item_queue_.empty()) { 247 while (!waiting_item_queue_.empty()) {
200 // We still have some items which are waiting for start to save. 248 // We still have some items which are waiting for start to save.
201 SaveItem* save_item = waiting_item_queue_.front(); 249 SaveItem* save_item = waiting_item_queue_.front();
202 waiting_item_queue_.pop(); 250 waiting_item_queue_.pop();
203 delete save_item; 251 delete save_item;
204 } 252 }
205 253
206 STLDeleteValues(&saved_success_items_); 254 STLDeleteValues(&saved_success_items_);
207 STLDeleteValues(&in_progress_items_); 255 STLDeleteValues(&in_progress_items_);
208 STLDeleteValues(&saved_failed_items_); 256 STLDeleteValues(&saved_failed_items_);
209 257
210 // The DownloadItem is owned by DownloadManager.
211 download_ = NULL;
212
213 file_manager_ = NULL; 258 file_manager_ = NULL;
214 } 259 }
215 260
216 GURL SavePackage::GetUrlToBeSaved() { 261 GURL SavePackage::GetUrlToBeSaved() {
217 // Instead of using tab_contents_.GetURL here, we use url() 262 // Instead of using tab_contents_.GetURL here, we use url()
218 // (which is the "real" url of the page) 263 // (which is the "real" url of the page)
219 // from the NavigationEntry because it reflects its' origin 264 // from the NavigationEntry because it reflects its' origin
220 // rather than the displayed one (returned by GetURL) which may be 265 // rather than the displayed one (returned by GetURL) which may be
221 // different (like having "view-source:" on the front). 266 // different (like having "view-source:" on the front).
222 NavigationEntry* active_entry = 267 NavigationEntry* active_entry =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 303
259 wait_state_ = START_PROCESS; 304 wait_state_ = START_PROCESS;
260 305
261 // Initialize the request context and resource dispatcher. 306 // Initialize the request context and resource dispatcher.
262 Profile* profile = tab_contents()->profile(); 307 Profile* profile = tab_contents()->profile();
263 if (!profile) { 308 if (!profile) {
264 NOTREACHED(); 309 NOTREACHED();
265 return false; 310 return false;
266 } 311 }
267 312
268 // Create the fake DownloadItem and display the view. 313 // Get the download manager and add ourselves as an observer.
269 DownloadManager* download_manager = 314 download_manager_ = tab_contents()->profile()->GetDownloadManager();
270 tab_contents()->profile()->GetDownloadManager(); 315 if (!download_manager_) {
271 download_ = new DownloadItem(download_manager, 316 NOTREACHED();
317 return false;
318 }
319
320 // Create the download item.
321 download_ = new DownloadItem(download_manager_,
272 saved_main_file_path_, 322 saved_main_file_path_,
273 page_url_, 323 page_url_,
274 profile->IsOffTheRecord()); 324 profile->IsOffTheRecord());
325 download_->AddObserver(this);
275 326
276 // Transfer the ownership to the download manager. We need the DownloadItem 327 // Transfer ownership to the download manager.
277 // to be alive as long as the Profile is alive. 328 download_manager_->SavePageDownloadStarted(download_);
278 download_manager->SavePageAsDownloadStarted(download_);
279
280 tab_contents()->OnStartDownload(download_);
281 329
282 // Check save type and process the save page job. 330 // Check save type and process the save page job.
283 if (save_type_ == SAVE_AS_COMPLETE_HTML) { 331 if (save_type_ == SAVE_AS_COMPLETE_HTML) {
284 // Get directory 332 // Get directory
285 DCHECK(!saved_main_directory_path_.empty()); 333 DCHECK(!saved_main_directory_path_.empty());
286 GetAllSavableResourceLinksForCurrentPage(); 334 GetAllSavableResourceLinksForCurrentPage();
287 } else { 335 } else {
288 wait_state_ = NET_FILES; 336 wait_state_ = NET_FILES;
289 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? 337 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
290 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : 338 SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 BrowserThread::PostTask( 680 BrowserThread::PostTask(
633 BrowserThread::FILE, FROM_HERE, 681 BrowserThread::FILE, FROM_HERE,
634 NewRunnableMethod(file_manager_, 682 NewRunnableMethod(file_manager_,
635 &SaveFileManager::RemoveSavedFileFromFileMap, 683 &SaveFileManager::RemoveSavedFileFromFileMap,
636 save_ids)); 684 save_ids));
637 685
638 finished_ = true; 686 finished_ = true;
639 wait_state_ = FAILED; 687 wait_state_ = FAILED;
640 688
641 // Inform the DownloadItem we have canceled whole save page job. 689 // Inform the DownloadItem we have canceled whole save page job.
642 download_->Cancel(false); 690 if (download_) {
691 download_->Cancel(false);
692 FinalizeDownloadEntry();
693 }
643 } 694 }
644 695
645 void SavePackage::CheckFinish() { 696 void SavePackage::CheckFinish() {
646 if (in_process_count() || finished_) 697 if (in_process_count() || finished_)
647 return; 698 return;
648 699
649 FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML && 700 FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML &&
650 saved_success_items_.size() > 1) ? 701 saved_success_items_.size() > 1) ?
651 saved_main_directory_path_ : FilePath(); 702 saved_main_directory_path_ : FilePath();
652 703
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin(); 736 for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
686 it != saved_failed_items_.end(); ++it) 737 it != saved_failed_items_.end(); ++it)
687 save_ids.push_back(it->second->save_id()); 738 save_ids.push_back(it->second->save_id());
688 739
689 BrowserThread::PostTask( 740 BrowserThread::PostTask(
690 BrowserThread::FILE, FROM_HERE, 741 BrowserThread::FILE, FROM_HERE,
691 NewRunnableMethod(file_manager_, 742 NewRunnableMethod(file_manager_,
692 &SaveFileManager::RemoveSavedFileFromFileMap, 743 &SaveFileManager::RemoveSavedFileFromFileMap,
693 save_ids)); 744 save_ids));
694 745
695 download_->OnAllDataSaved(all_save_items_count_); 746 if (download_) {
696 download_->MarkAsComplete(); 747 download_->OnAllDataSaved(all_save_items_count_);
748 download_->MarkAsComplete();
749 FinalizeDownloadEntry();
750 }
697 751
698 NotificationService::current()->Notify( 752 NotificationService::current()->Notify(
699 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 753 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
700 Source<SavePackage>(this), 754 Source<SavePackage>(this),
701 Details<GURL>(&page_url_)); 755 Details<GURL>(&page_url_));
702 } 756 }
703 757
704 // Called for updating end state. 758 // Called for updating end state.
705 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { 759 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
706 // Because we might have canceled this saving job before, 760 // Because we might have canceled this saving job before,
707 // so we might not find corresponding SaveItem. Just ignore it. 761 // so we might not find corresponding SaveItem. Just ignore it.
708 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); 762 SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
709 if (!save_item) 763 if (!save_item)
710 return; 764 return;
711 765
712 // Let SaveItem set end state. 766 // Let SaveItem set end state.
713 save_item->Finish(size, is_success); 767 save_item->Finish(size, is_success);
714 // Remove the associated save id and SavePackage. 768 // Remove the associated save id and SavePackage.
715 file_manager_->RemoveSaveFile(save_id, save_item->url(), this); 769 file_manager_->RemoveSaveFile(save_id, save_item->url(), this);
716 770
717 PutInProgressItemToSavedMap(save_item); 771 PutInProgressItemToSavedMap(save_item);
718 772
719 // Inform the DownloadItem to update UI. 773 // Inform the DownloadItem to update UI.
720 // We use the received bytes as number of saved files. 774 // We use the received bytes as number of saved files.
721 download_->Update(completed_count()); 775 if (download_)
776 download_->Update(completed_count());
722 777
723 if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM && 778 if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM &&
724 save_item->url() == page_url_ && !save_item->received_bytes()) { 779 save_item->url() == page_url_ && !save_item->received_bytes()) {
725 // If size of main HTML page is 0, treat it as disk error. 780 // If size of main HTML page is 0, treat it as disk error.
726 Cancel(false); 781 Cancel(false);
727 return; 782 return;
728 } 783 }
729 784
730 if (canceled()) { 785 if (canceled()) {
731 DCHECK(finished_); 786 DCHECK(finished_);
(...skipping 20 matching lines...) Expand all
752 return; 807 return;
753 } 808 }
754 SaveItem* save_item = it->second; 809 SaveItem* save_item = it->second;
755 810
756 save_item->Finish(0, false); 811 save_item->Finish(0, false);
757 812
758 PutInProgressItemToSavedMap(save_item); 813 PutInProgressItemToSavedMap(save_item);
759 814
760 // Inform the DownloadItem to update UI. 815 // Inform the DownloadItem to update UI.
761 // We use the received bytes as number of saved files. 816 // We use the received bytes as number of saved files.
762 download_->Update(completed_count()); 817 if (download_)
818 download_->Update(completed_count());
763 819
764 if (save_type_ == SAVE_AS_ONLY_HTML || 820 if (save_type_ == SAVE_AS_ONLY_HTML ||
765 save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { 821 save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
766 // We got error when saving page. Treat it as disk error. 822 // We got error when saving page. Treat it as disk error.
767 Cancel(true); 823 Cancel(true);
768 } 824 }
769 825
770 if (canceled()) { 826 if (canceled()) {
771 DCHECK(finished_); 827 DCHECK(finished_);
772 return; 828 return;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 const std::vector<GURL>& referrers_list, 1072 const std::vector<GURL>& referrers_list,
1017 const std::vector<GURL>& frames_list) { 1073 const std::vector<GURL>& frames_list) {
1018 if (wait_state_ != RESOURCES_LIST) 1074 if (wait_state_ != RESOURCES_LIST)
1019 return; 1075 return;
1020 1076
1021 DCHECK(resources_list.size() == referrers_list.size()); 1077 DCHECK(resources_list.size() == referrers_list.size());
1022 all_save_items_count_ = static_cast<int>(resources_list.size()) + 1078 all_save_items_count_ = static_cast<int>(resources_list.size()) +
1023 static_cast<int>(frames_list.size()); 1079 static_cast<int>(frames_list.size());
1024 1080
1025 // We use total bytes as the total number of files we want to save. 1081 // We use total bytes as the total number of files we want to save.
1026 download_->set_total_bytes(all_save_items_count_); 1082 if (download_)
1083 download_->set_total_bytes(all_save_items_count_);
1027 1084
1028 if (all_save_items_count_) { 1085 if (all_save_items_count_) {
1029 // Put all sub-resources to wait list. 1086 // Put all sub-resources to wait list.
1030 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) { 1087 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) {
1031 const GURL& u = resources_list[i]; 1088 const GURL& u = resources_list[i];
1032 DCHECK(u.is_valid()); 1089 DCHECK(u.is_valid());
1033 SaveFileCreateInfo::SaveFileSource save_source = u.SchemeIsFile() ? 1090 SaveFileCreateInfo::SaveFileSource save_source = u.SchemeIsFile() ?
1034 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : 1091 SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
1035 SaveFileCreateInfo::SAVE_FILE_FROM_NET; 1092 SaveFileCreateInfo::SAVE_FILE_FROM_NET;
1036 SaveItem* save_item = new SaveItem(u, referrers_list[i], 1093 SaveItem* save_item = new SaveItem(u, referrers_list[i],
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 bool SavePackage::IsSavableContents(const std::string& contents_mime_type) { 1361 bool SavePackage::IsSavableContents(const std::string& contents_mime_type) {
1305 // WebKit creates Document object when MIME type is application/xhtml+xml, 1362 // WebKit creates Document object when MIME type is application/xhtml+xml,
1306 // so we also support this MIME type. 1363 // so we also support this MIME type.
1307 return contents_mime_type == "text/html" || 1364 return contents_mime_type == "text/html" ||
1308 contents_mime_type == "text/xml" || 1365 contents_mime_type == "text/xml" ||
1309 contents_mime_type == "application/xhtml+xml" || 1366 contents_mime_type == "application/xhtml+xml" ||
1310 contents_mime_type == "text/plain" || 1367 contents_mime_type == "text/plain" ||
1311 contents_mime_type == "text/css" || 1368 contents_mime_type == "text/css" ||
1312 net::IsSupportedJavascriptMimeType(contents_mime_type.c_str()); 1369 net::IsSupportedJavascriptMimeType(contents_mime_type.c_str());
1313 } 1370 }
1371
1372 void SavePackage::StopObservation() {
1373 DCHECK(download_);
1374 DCHECK(download_manager_);
1375
1376 download_->RemoveObserver(this);
1377 download_ = NULL;
1378 download_manager_ = NULL;
1379 }
1380
1381 void SavePackage::OnDownloadUpdated(DownloadItem* download) {
1382 DCHECK(download_);
1383 DCHECK(download_ == download);
1384 DCHECK(download_manager_);
1385
1386 // Check for removal.
1387 if (download->state() == DownloadItem::REMOVING)
1388 StopObservation();
1389 }
1390
1391 void SavePackage::FinalizeDownloadEntry() {
1392 DCHECK(download_);
1393 DCHECK(download_manager_);
1394
1395 download_manager_->SavePageDownloadFinished(download_);
1396 StopObservation();
1397 }
OLDNEW
« chrome/browser/download/download_manager.cc ('K') | « content/browser/download/save_package.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698