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/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "content/browser/download/download_item_impl.h" | 22 #include "content/browser/download/download_item_impl.h" |
23 #include "content/browser/download/download_manager_impl.h" | 23 #include "content/browser/download/download_manager_impl.h" |
24 #include "content/browser/download/download_stats.h" | 24 #include "content/browser/download/download_stats.h" |
25 #include "content/browser/download/save_file.h" | 25 #include "content/browser/download/save_file.h" |
26 #include "content/browser/download/save_file_manager.h" | 26 #include "content/browser/download/save_file_manager.h" |
27 #include "content/browser/download/save_item.h" | 27 #include "content/browser/download/save_item.h" |
28 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 28 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
29 #include "content/browser/renderer_host/render_process_host_impl.h" | 29 #include "content/browser/renderer_host/render_process_host_impl.h" |
30 #include "content/browser/renderer_host/render_view_host_delegate.h" | 30 #include "content/browser/renderer_host/render_view_host_delegate.h" |
31 #include "content/browser/renderer_host/render_view_host_impl.h" | 31 #include "content/browser/renderer_host/render_view_host_impl.h" |
32 #include "content/common/frame_messages.h" | |
32 #include "content/common/view_messages.h" | 33 #include "content/common/view_messages.h" |
33 #include "content/public/browser/browser_context.h" | 34 #include "content/public/browser/browser_context.h" |
34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
35 #include "content/public/browser/content_browser_client.h" | 36 #include "content/public/browser/content_browser_client.h" |
36 #include "content/public/browser/download_manager_delegate.h" | 37 #include "content/public/browser/download_manager_delegate.h" |
37 #include "content/public/browser/navigation_entry.h" | 38 #include "content/public/browser/navigation_entry.h" |
38 #include "content/public/browser/notification_service.h" | 39 #include "content/public/browser/notification_service.h" |
39 #include "content/public/browser/notification_types.h" | 40 #include "content/public/browser/notification_types.h" |
40 #include "content/public/browser/render_frame_host.h" | 41 #include "content/public/browser/render_frame_host.h" |
41 #include "content/public/browser/resource_context.h" | 42 #include "content/public/browser/resource_context.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 } // namespace | 134 } // namespace |
134 | 135 |
135 const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] = | 136 const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] = |
136 FILE_PATH_LITERAL("html"); | 137 FILE_PATH_LITERAL("html"); |
137 | 138 |
138 SavePackage::SavePackage(WebContents* web_contents, | 139 SavePackage::SavePackage(WebContents* web_contents, |
139 SavePageType save_type, | 140 SavePageType save_type, |
140 const base::FilePath& file_full_path, | 141 const base::FilePath& file_full_path, |
141 const base::FilePath& directory_full_path) | 142 const base::FilePath& directory_full_path) |
142 : WebContentsObserver(web_contents), | 143 : WebContentsObserver(web_contents), |
144 number_of_frames_pending_response_(0), | |
143 file_manager_(NULL), | 145 file_manager_(NULL), |
144 download_manager_(NULL), | 146 download_manager_(NULL), |
145 download_(NULL), | 147 download_(NULL), |
146 page_url_(GetUrlToBeSaved()), | 148 page_url_(GetUrlToBeSaved()), |
147 saved_main_file_path_(file_full_path), | 149 saved_main_file_path_(file_full_path), |
148 saved_main_directory_path_(directory_full_path), | 150 saved_main_directory_path_(directory_full_path), |
149 title_(web_contents->GetTitle()), | 151 title_(web_contents->GetTitle()), |
150 start_tick_(base::TimeTicks::Now()), | 152 start_tick_(base::TimeTicks::Now()), |
151 finished_(false), | 153 finished_(false), |
152 mhtml_finishing_(false), | 154 mhtml_finishing_(false), |
(...skipping 13 matching lines...) Expand all Loading... | |
166 (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML)); | 168 (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML)); |
167 DCHECK(!saved_main_file_path_.empty() && | 169 DCHECK(!saved_main_file_path_.empty() && |
168 saved_main_file_path_.value().length() <= kMaxFilePathLength); | 170 saved_main_file_path_.value().length() <= kMaxFilePathLength); |
169 DCHECK(!saved_main_directory_path_.empty() && | 171 DCHECK(!saved_main_directory_path_.empty() && |
170 saved_main_directory_path_.value().length() < kMaxFilePathLength); | 172 saved_main_directory_path_.value().length() < kMaxFilePathLength); |
171 InternalInit(); | 173 InternalInit(); |
172 } | 174 } |
173 | 175 |
174 SavePackage::SavePackage(WebContents* web_contents) | 176 SavePackage::SavePackage(WebContents* web_contents) |
175 : WebContentsObserver(web_contents), | 177 : WebContentsObserver(web_contents), |
178 number_of_frames_pending_response_(0), | |
176 file_manager_(NULL), | 179 file_manager_(NULL), |
177 download_manager_(NULL), | 180 download_manager_(NULL), |
178 download_(NULL), | 181 download_(NULL), |
179 page_url_(GetUrlToBeSaved()), | 182 page_url_(GetUrlToBeSaved()), |
180 title_(web_contents->GetTitle()), | 183 title_(web_contents->GetTitle()), |
181 start_tick_(base::TimeTicks::Now()), | 184 start_tick_(base::TimeTicks::Now()), |
182 finished_(false), | 185 finished_(false), |
183 mhtml_finishing_(false), | 186 mhtml_finishing_(false), |
184 user_canceled_(false), | 187 user_canceled_(false), |
185 disk_error_occurred_(false), | 188 disk_error_occurred_(false), |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 download_ = item; | 332 download_ = item; |
330 download_->AddObserver(this); | 333 download_->AddObserver(this); |
331 // Confirm above didn't delete the tab out from under us. | 334 // Confirm above didn't delete the tab out from under us. |
332 if (!download_created_callback.is_null()) | 335 if (!download_created_callback.is_null()) |
333 download_created_callback.Run(download_); | 336 download_created_callback.Run(download_); |
334 | 337 |
335 // Check save type and process the save page job. | 338 // Check save type and process the save page job. |
336 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { | 339 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { |
337 // Get directory | 340 // Get directory |
338 DCHECK(!saved_main_directory_path_.empty()); | 341 DCHECK(!saved_main_directory_path_.empty()); |
339 GetAllSavableResourceLinksForCurrentPage(); | 342 GetSavableResourceLinksForCurrentPage(); |
340 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) { | 343 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) { |
341 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind( | 344 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind( |
342 &SavePackage::OnMHTMLGenerated, this)); | 345 &SavePackage::OnMHTMLGenerated, this)); |
343 } else { | 346 } else { |
344 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_) << save_type_; | 347 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_) << save_type_; |
345 wait_state_ = NET_FILES; | 348 wait_state_ = NET_FILES; |
346 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? | 349 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? |
347 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : | 350 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : |
348 SaveFileCreateInfo::SAVE_FILE_FROM_NET; | 351 SaveFileCreateInfo::SAVE_FILE_FROM_NET; |
349 SaveItem* save_item = new SaveItem(page_url_, | 352 SaveItem* save_item = new SaveItem(page_url_, |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
996 if (waiting_item_queue_.size()) { | 999 if (waiting_item_queue_.size()) { |
997 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); | 1000 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); |
998 SaveNextFile(false); | 1001 SaveNextFile(false); |
999 } | 1002 } |
1000 } | 1003 } |
1001 } | 1004 } |
1002 | 1005 |
1003 bool SavePackage::OnMessageReceived(const IPC::Message& message) { | 1006 bool SavePackage::OnMessageReceived(const IPC::Message& message) { |
1004 bool handled = true; | 1007 bool handled = true; |
1005 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) | 1008 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) |
1006 IPC_MESSAGE_HANDLER(ViewHostMsg_SendCurrentPageAllSavableResourceLinks, | |
1007 OnReceivedSavableResourceLinksForCurrentPage) | |
1008 IPC_MESSAGE_HANDLER(ViewHostMsg_SendSerializedHtmlData, | 1009 IPC_MESSAGE_HANDLER(ViewHostMsg_SendSerializedHtmlData, |
1009 OnReceivedSerializedHtmlData) | 1010 OnReceivedSerializedHtmlData) |
1010 IPC_MESSAGE_UNHANDLED(handled = false) | 1011 IPC_MESSAGE_UNHANDLED(handled = false) |
1011 IPC_END_MESSAGE_MAP() | 1012 IPC_END_MESSAGE_MAP() |
1012 return handled; | 1013 return handled; |
1013 } | 1014 } |
1014 | 1015 |
1016 bool SavePackage::OnMessageReceived(const IPC::Message& message, | |
1017 RenderFrameHost* render_frame_host) { | |
1018 bool handled = true; | |
1019 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, render_frame_host) | |
1020 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse, | |
1021 OnSavableResourceLinksResponse) | |
1022 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError, | |
1023 OnSavableResourceLinksError) | |
1024 IPC_MESSAGE_UNHANDLED(handled = false) | |
1025 IPC_END_MESSAGE_MAP() | |
1026 return handled; | |
1027 } | |
1028 | |
1015 // After finishing all SaveItems which need to get data from net. | 1029 // After finishing all SaveItems which need to get data from net. |
1016 // We collect all URLs which have local storage and send the | 1030 // We collect all URLs which have local storage and send the |
1017 // map:(originalURL:currentLocalPath) to render process (backend). | 1031 // map:(originalURL:currentLocalPath) to render process (backend). |
1018 // Then render process will serialize DOM and send data to us. | 1032 // Then render process will serialize DOM and send data to us. |
1019 void SavePackage::GetSerializedHtmlDataForCurrentPageWithLocalLinks() { | 1033 void SavePackage::GetSerializedHtmlDataForCurrentPageWithLocalLinks() { |
1020 if (wait_state_ != HTML_DATA) | 1034 if (wait_state_ != HTML_DATA) |
1021 return; | 1035 return; |
1022 std::vector<GURL> saved_links; | 1036 std::vector<GURL> saved_links; |
1023 std::vector<base::FilePath> saved_file_paths; | 1037 std::vector<base::FilePath> saved_file_paths; |
1024 int successful_started_items_count = 0; | 1038 int successful_started_items_count = 0; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1135 file_manager_, | 1149 file_manager_, |
1136 save_item->save_id(), | 1150 save_item->save_id(), |
1137 save_item->url(), | 1151 save_item->url(), |
1138 id, | 1152 id, |
1139 true)); | 1153 true)); |
1140 } | 1154 } |
1141 } | 1155 } |
1142 | 1156 |
1143 // Ask for all savable resource links from backend, include main frame and | 1157 // Ask for all savable resource links from backend, include main frame and |
1144 // sub-frame. | 1158 // sub-frame. |
1145 void SavePackage::GetAllSavableResourceLinksForCurrentPage() { | 1159 void SavePackage::GetSavableResourceLinksForCurrentPage() { |
1146 if (wait_state_ != START_PROCESS) | 1160 if (wait_state_ != START_PROCESS) |
1147 return; | 1161 return; |
1148 | 1162 |
1149 wait_state_ = RESOURCES_LIST; | 1163 wait_state_ = RESOURCES_LIST; |
1150 Send(new ViewMsg_GetAllSavableResourceLinksForCurrentPage(routing_id(), | 1164 |
1151 page_url_)); | 1165 DCHECK_EQ(0, number_of_frames_pending_response_); |
1166 web_contents()->ForEachFrame(base::Bind( | |
1167 &SavePackage::GetSavableResourceLinksForFrame, | |
1168 base::Unretained(this))); // Safe, because ForEachFrame is synchronous. | |
1169 DCHECK_LT(0, number_of_frames_pending_response_); | |
1152 } | 1170 } |
1153 | 1171 |
1154 // Give backend the lists which contain all resource links that have local | 1172 void SavePackage::GetSavableResourceLinksForFrame(RenderFrameHost* target) { |
1155 // storage, after which, render process will serialize DOM for generating | 1173 number_of_frames_pending_response_++; |
1156 // HTML data. | 1174 target->Send(new FrameMsg_GetSavableResourceLinks(target->GetRoutingID())); |
1157 void SavePackage::OnReceivedSavableResourceLinksForCurrentPage( | 1175 } |
1176 | |
1177 void SavePackage::OnSavableResourceLinksResponse( | |
1178 RenderFrameHost* sender, | |
1179 const GURL& frame_url, | |
1158 const std::vector<GURL>& resources_list, | 1180 const std::vector<GURL>& resources_list, |
1159 const std::vector<Referrer>& referrers_list, | 1181 const std::vector<Referrer>& referrers_list) { |
1160 const std::vector<GURL>& frames_list) { | |
1161 if (wait_state_ != RESOURCES_LIST) | 1182 if (wait_state_ != RESOURCES_LIST) |
1162 return; | 1183 return; |
1163 | 1184 |
1164 if (resources_list.size() != referrers_list.size()) | 1185 if (resources_list.size() != referrers_list.size()) |
1165 return; | 1186 return; |
1166 | 1187 |
1167 all_save_items_count_ = static_cast<int>(resources_list.size()) + | 1188 // Add all sub-resources to wait list. |
1168 static_cast<int>(frames_list.size()); | 1189 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) { |
1190 const GURL& u = resources_list[i]; | |
1191 if (!u.is_valid()) { | |
nasko
2015/09/17 21:18:24
nit: no {} for one line if statements (this one an
Łukasz Anforowicz
2015/09/18 18:44:18
Done - I see that the rest of the file indeed cons
| |
1192 continue; | |
1193 } | |
1194 if (unique_urls_to_save_.count(u)) { | |
1195 continue; | |
1196 } | |
1197 unique_urls_to_save_.insert(u); | |
1198 | |
1199 SaveFileCreateInfo::SaveFileSource save_source = | |
1200 u.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE | |
1201 : SaveFileCreateInfo::SAVE_FILE_FROM_NET; | |
1202 SaveItem* save_item = new SaveItem(u, referrers_list[i], this, save_source); | |
1203 waiting_item_queue_.push(save_item); | |
1204 } | |
1205 | |
1206 // Store savable frame_url for later processing. | |
1207 if (frame_url.is_valid()) { | |
1208 frame_urls_to_save_.push_back(frame_url); | |
1209 } | |
1210 | |
1211 CompleteSavableResourceLinksResponseFromFrame(); | |
1212 } | |
1213 | |
1214 void SavePackage::OnSavableResourceLinksError(RenderFrameHost* sender) { | |
1215 CompleteSavableResourceLinksResponseFromFrame(); | |
1216 } | |
1217 | |
1218 void SavePackage::CompleteSavableResourceLinksResponseFromFrame() { | |
1219 --number_of_frames_pending_response_; | |
1220 DCHECK_LE(0, number_of_frames_pending_response_); | |
1221 if (number_of_frames_pending_response_ != 0) { | |
1222 return; // Need to wait for more responses from RenderFrames. | |
1223 } | |
1224 | |
1225 // Add frame urls to the waiting_item_queue_. This is done *after* processing | |
1226 // all savable resource links (i.e. in OnSavableResourceLinksResponse), to | |
1227 // prefer their referrers in cases where the frame url has already been | |
1228 // covered by savable resource links. | |
1229 for (auto& frame_url : frame_urls_to_save_) { | |
1230 DCHECK(frame_url.is_valid()); | |
1231 if (0 == unique_urls_to_save_.count(frame_url)) { | |
1232 unique_urls_to_save_.insert(frame_url); | |
1233 SaveItem* save_item = new SaveItem( | |
1234 frame_url, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM); | |
1235 waiting_item_queue_.push(save_item); | |
1236 } | |
1237 } | |
1238 | |
1239 all_save_items_count_ = static_cast<int>(waiting_item_queue_.size()); | |
1169 | 1240 |
1170 // We use total bytes as the total number of files we want to save. | 1241 // We use total bytes as the total number of files we want to save. |
1171 // Hack to avoid touching download_ after user cancel. | 1242 // Hack to avoid touching download_ after user cancel. |
1172 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem | 1243 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem |
1173 // with SavePackage flow. | 1244 // with SavePackage flow. |
1174 if (download_ && (download_->GetState() == DownloadItem::IN_PROGRESS)) | 1245 if (download_ && (download_->GetState() == DownloadItem::IN_PROGRESS)) |
1175 download_->SetTotalBytes(all_save_items_count_); | 1246 download_->SetTotalBytes(all_save_items_count_); |
1176 | 1247 |
1177 if (all_save_items_count_) { | 1248 if (all_save_items_count_) { |
1178 // Put all sub-resources to wait list. | |
1179 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) { | |
1180 const GURL& u = resources_list[i]; | |
1181 DCHECK(u.is_valid()); | |
1182 SaveFileCreateInfo::SaveFileSource save_source = u.SchemeIsFile() ? | |
1183 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : | |
1184 SaveFileCreateInfo::SAVE_FILE_FROM_NET; | |
1185 SaveItem* save_item = new SaveItem(u, referrers_list[i], | |
1186 this, save_source); | |
1187 waiting_item_queue_.push(save_item); | |
1188 } | |
1189 // Put all HTML resources to wait list. | |
1190 for (int i = 0; i < static_cast<int>(frames_list.size()); ++i) { | |
1191 const GURL& u = frames_list[i]; | |
1192 DCHECK(u.is_valid()); | |
1193 SaveItem* save_item = new SaveItem( | |
1194 u, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM); | |
1195 waiting_item_queue_.push(save_item); | |
1196 } | |
1197 wait_state_ = NET_FILES; | 1249 wait_state_ = NET_FILES; |
1250 | |
1251 // Give backend the lists which contain all resource links that have local | |
1252 // storage, after which, render process will serialize DOM for generating | |
1253 // HTML data. | |
1198 DoSavingProcess(); | 1254 DoSavingProcess(); |
1199 } else { | 1255 } else { |
1200 // No resource files need to be saved, treat it as user cancel. | 1256 // No savable frames and/or resources - treat it as user cancel. |
1201 Cancel(true); | 1257 Cancel(true); |
1202 } | 1258 } |
1203 } | 1259 } |
1204 | 1260 |
1205 base::FilePath SavePackage::GetSuggestedNameForSaveAs( | 1261 base::FilePath SavePackage::GetSuggestedNameForSaveAs( |
1206 bool can_save_as_complete, | 1262 bool can_save_as_complete, |
1207 const std::string& contents_mime_type, | 1263 const std::string& contents_mime_type, |
1208 const std::string& accept_langs) { | 1264 const std::string& accept_langs) { |
1209 base::FilePath name_with_proper_ext = base::FilePath::FromUTF16Unsafe(title_); | 1265 base::FilePath name_with_proper_ext = base::FilePath::FromUTF16Unsafe(title_); |
1210 | 1266 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1437 | 1493 |
1438 void SavePackage::FinalizeDownloadEntry() { | 1494 void SavePackage::FinalizeDownloadEntry() { |
1439 DCHECK(download_); | 1495 DCHECK(download_); |
1440 DCHECK(download_manager_); | 1496 DCHECK(download_manager_); |
1441 | 1497 |
1442 download_manager_->OnSavePackageSuccessfullyFinished(download_); | 1498 download_manager_->OnSavePackageSuccessfullyFinished(download_); |
1443 StopObservation(); | 1499 StopObservation(); |
1444 } | 1500 } |
1445 | 1501 |
1446 } // namespace content | 1502 } // namespace content |
OLD | NEW |