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

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

Issue 1373573002: ABANDONED: OOPIFs: Moving stitching of local paths from renderer to browser process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@page-serialization-recursive-begone
Patch Set: Self-review. Created 5 years, 2 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/common/frame_messages.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 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"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/i18n/file_util_icu.h" 12 #include "base/i18n/file_util_icu.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/strings/string_piece.h" 16 #include "base/strings/string_piece.h"
17 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
18 #include "base/strings/sys_string_conversions.h" 18 #include "base/strings/sys_string_conversions.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
21 #include "components/url_formatter/url_formatter.h" 21 #include "components/url_formatter/url_formatter.h"
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/frame_host/frame_tree.h"
29 #include "content/browser/frame_host/frame_tree_node.h"
28 #include "content/browser/loader/resource_dispatcher_host_impl.h" 30 #include "content/browser/loader/resource_dispatcher_host_impl.h"
29 #include "content/browser/renderer_host/render_process_host_impl.h" 31 #include "content/browser/renderer_host/render_process_host_impl.h"
30 #include "content/browser/renderer_host/render_view_host_delegate.h" 32 #include "content/browser/renderer_host/render_view_host_delegate.h"
31 #include "content/browser/renderer_host/render_view_host_impl.h" 33 #include "content/browser/renderer_host/render_view_host_impl.h"
34 #include "content/browser/web_contents/web_contents_impl.h"
32 #include "content/common/frame_messages.h" 35 #include "content/common/frame_messages.h"
33 #include "content/common/view_messages.h"
34 #include "content/public/browser/browser_context.h" 36 #include "content/public/browser/browser_context.h"
35 #include "content/public/browser/browser_thread.h" 37 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/content_browser_client.h" 38 #include "content/public/browser/content_browser_client.h"
37 #include "content/public/browser/download_manager_delegate.h" 39 #include "content/public/browser/download_manager_delegate.h"
38 #include "content/public/browser/navigation_entry.h" 40 #include "content/public/browser/navigation_entry.h"
39 #include "content/public/browser/notification_service.h" 41 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h" 42 #include "content/public/browser/notification_types.h"
41 #include "content/public/browser/render_frame_host.h" 43 #include "content/public/browser/render_frame_host.h"
42 #include "content/public/browser/resource_context.h" 44 #include "content/public/browser/resource_context.h"
43 #include "content/public/browser/web_contents.h" 45 #include "content/public/browser/web_contents.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 void ResumeRequest() const override {} 126 void ResumeRequest() const override {}
125 void CancelRequest() const override {} 127 void CancelRequest() const override {}
126 std::string DebugString() const override { 128 std::string DebugString() const override {
127 return "SavePackage DownloadRequestHandle"; 129 return "SavePackage DownloadRequestHandle";
128 } 130 }
129 131
130 private: 132 private:
131 base::WeakPtr<SavePackage> save_package_; 133 base::WeakPtr<SavePackage> save_package_;
132 }; 134 };
133 135
136 int GetFrameTreeNodeId(RenderFrameHost* render_frame_host) {
137 auto rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host);
138 return rfhi->frame_tree_node()->frame_tree_node_id();
139 }
140
134 } // namespace 141 } // namespace
135 142
136 const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] = 143 const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] =
137 FILE_PATH_LITERAL("html"); 144 FILE_PATH_LITERAL("html");
138 145
139 SavePackage::SavePackage(WebContents* web_contents, 146 SavePackage::SavePackage(WebContents* web_contents,
140 SavePageType save_type, 147 SavePageType save_type,
141 const base::FilePath& file_full_path, 148 const base::FilePath& file_full_path,
142 const base::FilePath& directory_full_path) 149 const base::FilePath& directory_full_path)
143 : WebContentsObserver(web_contents), 150 : WebContentsObserver(web_contents),
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 GetSavableResourceLinks(); 349 GetSavableResourceLinks();
343 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) { 350 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) {
344 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind( 351 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind(
345 &SavePackage::OnMHTMLGenerated, this)); 352 &SavePackage::OnMHTMLGenerated, this));
346 } else { 353 } else {
347 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_) << save_type_; 354 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_) << save_type_;
348 wait_state_ = NET_FILES; 355 wait_state_ = NET_FILES;
349 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? 356 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
350 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : 357 SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
351 SaveFileCreateInfo::SAVE_FILE_FROM_NET; 358 SaveFileCreateInfo::SAVE_FILE_FROM_NET;
352 SaveItem* save_item = new SaveItem(page_url_, 359 SaveItem* save_item = new SaveItem(page_url_, this, save_source);
353 Referrer(), 360 save_item->set_frame_tree_node_id(
354 this, 361 GetFrameTreeNodeId(web_contents()->GetMainFrame()));
355 save_source);
356 // Add this item to waiting list. 362 // Add this item to waiting list.
357 waiting_item_queue_.push(save_item); 363 waiting_item_queue_.push(save_item);
358 all_save_items_count_ = 1; 364 all_save_items_count_ = 1;
359 download_->SetTotalBytes(1); 365 download_->SetTotalBytes(1);
360 366
361 DoSavingProcess(); 367 DoSavingProcess();
362 } 368 }
363 } 369 }
364 370
365 void SavePackage::OnMHTMLGenerated(int64 size) { 371 void SavePackage::OnMHTMLGenerated(int64 size) {
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 } 1010 }
1005 1011
1006 bool SavePackage::OnMessageReceived(const IPC::Message& message, 1012 bool SavePackage::OnMessageReceived(const IPC::Message& message,
1007 RenderFrameHost* render_frame_host) { 1013 RenderFrameHost* render_frame_host) {
1008 bool handled = true; 1014 bool handled = true;
1009 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, render_frame_host) 1015 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, render_frame_host)
1010 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse, 1016 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse,
1011 OnSavableResourceLinksResponse) 1017 OnSavableResourceLinksResponse)
1012 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError, 1018 IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError,
1013 OnSavableResourceLinksError) 1019 OnSavableResourceLinksError)
1014 IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedHtmlWithLocalLinksResponse, 1020 IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedHtmlFragment,
1015 OnSerializedHtmlWithLocalLinksResponse) 1021 OnSerializedHtmlFragment)
1022 IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedLocalPathForSubFrame,
1023 OnSerializedLocalPathForSubFrame)
1024 IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedLocalPathForSavableResource,
1025 OnSerializedLocalPathForSavableResource)
1026 IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedEndOfFrame,
1027 OnSerializedEndOfFrame)
1016 IPC_MESSAGE_UNHANDLED(handled = false) 1028 IPC_MESSAGE_UNHANDLED(handled = false)
1017 IPC_END_MESSAGE_MAP() 1029 IPC_END_MESSAGE_MAP()
1018 return handled; 1030 return handled;
1019 } 1031 }
1020 1032
1021 // After finishing all SaveItems which need to get data from net. 1033 // After finishing all SaveItems which need to get data from net.
1022 // We collect all URLs which have local storage and send the 1034 // We collect all URLs which have local storage and send the
1023 // map:(originalURL:currentLocalPath) to render process (backend). 1035 // map:(originalURL:currentLocalPath) to render process (backend).
1024 // Then render process will serialize DOM and send data to us. 1036 // Then render process will serialize DOM and send data to us.
1025 void SavePackage::GetSerializedHtmlWithLocalLinks() { 1037 void SavePackage::GetSerializedHtmlWithLocalLinks() {
1026 if (wait_state_ != HTML_DATA) 1038 if (wait_state_ != HTML_DATA)
1027 return; 1039 return;
1028 std::vector<GURL> saved_links;
1029 std::vector<base::FilePath> saved_file_paths;
1030 int successful_started_items_count = 0; 1040 int successful_started_items_count = 0;
1031 1041
1032 // Collect all saved items which have local storage. 1042 // Count all saved items which have local storage.
1033 // First collect the status of all the resource files and check whether they
1034 // have created local files although they have not been completely saved.
1035 // If yes, the file can be saved. Otherwise, there is a disk error, so we
1036 // need to cancel the page saving job.
1037 for (SaveUrlItemMap::iterator it = in_progress_items_.begin(); 1043 for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
1038 it != in_progress_items_.end(); ++it) { 1044 it != in_progress_items_.end(); ++it) {
1039 DCHECK(it->second->save_source() == 1045 DCHECK(it->second->save_source() ==
1040 SaveFileCreateInfo::SAVE_FILE_FROM_DOM); 1046 SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
1041 if (it->second->has_final_name()) 1047 if (it->second->has_final_name())
1042 successful_started_items_count++; 1048 successful_started_items_count++;
1043 saved_links.push_back(it->second->url());
1044 saved_file_paths.push_back(it->second->file_name());
1045 } 1049 }
1046 1050
1047 // If not all file of HTML resource have been started, then wait. 1051 // If not all file of HTML resource have been started, then wait.
1048 if (successful_started_items_count != in_process_count()) 1052 if (successful_started_items_count != in_process_count())
1049 return; 1053 return;
1050 1054
1051 // Collect all saved success items.
1052 for (SavedItemMap::iterator it = saved_success_items_.begin();
1053 it != saved_success_items_.end(); ++it) {
1054 DCHECK(it->second->has_final_name());
1055 saved_links.push_back(it->second->url());
1056 saved_file_paths.push_back(it->second->file_name());
1057 }
1058
1059 // Get the relative directory name.
1060 base::FilePath relative_dir_name = saved_main_directory_path_.BaseName();
1061
1062 // Ask all frames for their serialized data. 1055 // Ask all frames for their serialized data.
1063 DCHECK_EQ(0, number_of_frames_pending_response_); 1056 DCHECK_EQ(0, number_of_frames_pending_response_);
1064 web_contents()->ForEachFrame(base::Bind( 1057 web_contents()->ForEachFrame(base::Bind(
1065 &SavePackage::GetSerializedHtmlWithLocalLinksForFrame, 1058 &SavePackage::GetSerializedHtmlWithLocalLinksForFrame,
1066 base::Unretained(this), // Safe, because ForEachFrame is synchronous. 1059 base::Unretained(this))); // Safe, because ForEachFrame is synchronous.
1067 saved_links, saved_file_paths, relative_dir_name));
1068 DCHECK_LT(0, number_of_frames_pending_response_); 1060 DCHECK_LT(0, number_of_frames_pending_response_);
1069 } 1061 }
1070 1062
1071 void SavePackage::GetSerializedHtmlWithLocalLinksForFrame( 1063 void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
1072 const std::vector<GURL>& saved_links,
1073 const std::vector<base::FilePath>& saved_file_paths,
1074 const base::FilePath& relative_dir_name,
1075 RenderFrameHost* target) { 1064 RenderFrameHost* target) {
1076 number_of_frames_pending_response_++; 1065 number_of_frames_pending_response_++;
1077 target->Send(new FrameMsg_GetSerializedHtmlWithLocalLinks( 1066 target->Send(
1078 target->GetRoutingID(), saved_links, saved_file_paths, 1067 new FrameMsg_GetSerializedHtmlWithLocalLinks(target->GetRoutingID()));
1079 relative_dir_name));
1080 } 1068 }
1081 1069
1082 // Process the serialized HTML content data of a specified frame 1070 void SavePackage::OnSerializedHtmlFragment(RenderFrameHost* sender,
1083 // retrieved from the renderer process. 1071 const std::string& data) {
1084 void SavePackage::OnSerializedHtmlWithLocalLinksResponse(
1085 RenderFrameHost* sender,
1086 const GURL& frame_url,
1087 const std::string& data,
1088 int32 status) {
1089 WebPageSerializerClient::PageSerializationStatus flag =
1090 static_cast<WebPageSerializerClient::PageSerializationStatus>(status);
1091
1092 // When calling WebPageSerializer::serialize in non-recursive mode, the
1093 // AllFramesAreFinished is redundant - it is sent by each frame right after
1094 // CurrentFrameIsFinished. Therefore we ignore AllFramesAreFinished and
1095 // instead track pending frames in |number_of_frames_pending_response_|.
1096 if (flag == WebPageSerializerClient::AllFramesAreFinished)
1097 return;
1098
1099 // Check current state.
1100 if (wait_state_ != HTML_DATA) 1072 if (wait_state_ != HTML_DATA)
1101 return; 1073 return;
1102 1074
1103 int id = contents_id(); 1075 int frame_tree_node_id = GetFrameTreeNodeId(sender);
1104 1076 SaveItem* save_item =
1105 SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec()); 1077 FindInProgressSaveItemByFrameTreeNodeID(frame_tree_node_id);
1106 if (it == in_progress_items_.end()) { 1078 if (!save_item) {
1107 for (SavedItemMap::iterator saved_it = saved_success_items_.begin(); 1079 LogWriteToAlreadyCompletedOrFailedSaveItem(frame_tree_node_id);
1108 saved_it != saved_success_items_.end(); ++saved_it) {
1109 if (saved_it->second->url() == frame_url) {
1110 wrote_to_completed_file_ = true;
1111 break;
1112 }
1113 }
1114
1115 it = saved_failed_items_.find(frame_url.spec());
1116 if (it != saved_failed_items_.end())
1117 wrote_to_failed_file_ = true;
1118
1119 return; 1080 return;
1120 } 1081 }
1121 1082
1122 SaveItem* save_item = it->second;
1123 DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM); 1083 DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
1124
1125 if (!data.empty()) { 1084 if (!data.empty()) {
1126 // Prepare buffer for saving HTML data. 1085 // Prepare buffer for saving HTML data.
1127 scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size())); 1086 scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size()));
1128 memcpy(new_data->data(), data.data(), data.size()); 1087 memcpy(new_data->data(), data.data(), data.size());
1129 1088
1130 // Call write file functionality in file thread. 1089 // Call write file functionality in file thread.
1131 BrowserThread::PostTask( 1090 BrowserThread::PostTask(
1132 BrowserThread::FILE, FROM_HERE, 1091 BrowserThread::FILE, FROM_HERE,
1133 base::Bind(&SaveFileManager::UpdateSaveProgress, 1092 base::Bind(&SaveFileManager::UpdateSaveProgress, file_manager_,
1134 file_manager_, 1093 save_item->save_id(), new_data,
1135 save_item->save_id(),
1136 new_data,
1137 static_cast<int>(data.size()))); 1094 static_cast<int>(data.size())));
1138 } 1095 }
1096 }
1097
1098 void SavePackage::OnSerializedLocalPathForSubFrame(
1099 RenderFrameHost* sender,
1100 int render_frame_or_proxy_routing_id) {
1101 if (wait_state_ != HTML_DATA)
1102 return;
1103
1104 FrameTreeNode* frame_tree_node =
dcheng 2015/09/30 05:37:32 It seems like this code would benefit from a FTN -
Łukasz Anforowicz 2015/10/01 20:39:58 Good point. Done. I also found out that looking
1105 static_cast<WebContentsImpl*>(web_contents())
1106 ->GetFrameTree()
1107 ->FindByRoutingID(sender->GetProcess()->GetID(),
1108 render_frame_or_proxy_routing_id);
1109 if (!frame_tree_node)
1110 return;
1111
1112 SerializeLocalPathForSaveItem(sender,
1113 FindInProgressSaveItemByFrameTreeNodeID(
1114 frame_tree_node->frame_tree_node_id()),
1115 frame_tree_node->current_url());
1116 }
1117
1118 void SavePackage::OnSerializedLocalPathForSavableResource(
1119 RenderFrameHost* sender,
1120 const GURL& savable_resource) {
1121 if (wait_state_ != HTML_DATA)
1122 return;
1123 if (!savable_resource.is_valid())
1124 return;
1125
1126 // Find SaveItem by URL.
1127 auto it =
1128 std::find_if(in_progress_items_.begin(), in_progress_items_.end(),
1129 [&savable_resource](const SaveUrlItemMap::value_type& v) {
1130 DCHECK(v.second->has_final_name());
1131 return v.second->url() == savable_resource;
1132 });
1133 SaveItem* save_item = (it == in_progress_items_.end()) ? nullptr : it->second;
1134
1135 SerializeLocalPathForSaveItem(sender, save_item, savable_resource);
1136 }
1137
1138 void SavePackage::OnSerializedEndOfFrame(RenderFrameHost* sender) {
1139 if (wait_state_ != HTML_DATA)
1140 return;
1141
1142 int frame_tree_node_id = GetFrameTreeNodeId(sender);
1143 SaveItem* save_item =
1144 FindInProgressSaveItemByFrameTreeNodeID(frame_tree_node_id);
1145 if (!save_item) {
1146 LogWriteToAlreadyCompletedOrFailedSaveItem(frame_tree_node_id);
1147 return;
1148 }
1149
1150 int id = contents_id();
1139 1151
1140 // Current frame is completed saving, call finish in file thread. 1152 // Current frame is completed saving, call finish in file thread.
1141 if (flag == WebPageSerializerClient::CurrentFrameIsFinished) { 1153 DVLOG(20) << " " << __FUNCTION__ << "()"
1142 DVLOG(20) << " " << __FUNCTION__ << "()" 1154 << " save_id = " << save_item->save_id() << " url = \""
1143 << " save_id = " << save_item->save_id() 1155 << save_item->url().spec() << "\"";
1144 << " url = \"" << save_item->url().spec() << "\""; 1156 BrowserThread::PostTask(
1145 BrowserThread::PostTask( 1157 BrowserThread::FILE, FROM_HERE,
1146 BrowserThread::FILE, FROM_HERE, 1158 base::Bind(&SaveFileManager::SaveFinished, file_manager_,
1147 base::Bind(&SaveFileManager::SaveFinished, 1159 save_item->save_id(), save_item->url(), id, true));
1148 file_manager_, 1160 number_of_frames_pending_response_--;
1149 save_item->save_id(), 1161 DCHECK_LE(0, number_of_frames_pending_response_);
1150 save_item->url(),
1151 id,
1152 true));
1153 number_of_frames_pending_response_--;
1154 DCHECK_LE(0, number_of_frames_pending_response_);
1155 }
1156 1162
1157 // If all frames are finished saving, we need to close the remaining 1163 // If the all frames are finished saving, we need to close the
1158 // SaveItems. 1164 // remaining SaveItems.
1159 if (number_of_frames_pending_response_ == 0) { 1165 if (number_of_frames_pending_response_ == 0) {
1160 for (SaveUrlItemMap::iterator it = in_progress_items_.begin(); 1166 for (const auto pair : in_progress_items_) {
dcheng 2015/09/30 05:37:32 const auto&, since this copies otherwise.
1161 it != in_progress_items_.end(); ++it) {
1162 DVLOG(20) << " " << __FUNCTION__ << "()" 1167 DVLOG(20) << " " << __FUNCTION__ << "()"
1163 << " save_id = " << it->second->save_id() << " url = \"" 1168 << " save_id = " << pair.second->save_id() << " url = \""
1164 << it->second->url().spec() << "\""; 1169 << pair.second->url().spec() << "\"";
1165 BrowserThread::PostTask( 1170 BrowserThread::PostTask(
1166 BrowserThread::FILE, FROM_HERE, 1171 BrowserThread::FILE, FROM_HERE,
1167 base::Bind(&SaveFileManager::SaveFinished, file_manager_, 1172 base::Bind(&SaveFileManager::SaveFinished, file_manager_,
1168 it->second->save_id(), it->second->url(), id, true)); 1173 pair.second->save_id(), pair.second->url(), id, true));
1169 } 1174 }
1170 } 1175 }
1171 } 1176 }
1172 1177
1178 void SavePackage::SerializeLocalPathForSaveItem(RenderFrameHost* sender,
1179 SaveItem* save_item,
1180 const GURL& fallback_url) {
1181 std::string attr_value;
1182 if (save_item) {
1183 base::FilePath relative_path(FILE_PATH_LITERAL("."));
1184 relative_path = relative_path.Append(saved_main_directory_path_.BaseName());
1185 relative_path = relative_path.Append(save_item->file_name());
1186 attr_value = relative_path.AsUTF8Unsafe();
1187 } else {
1188 attr_value = fallback_url.spec();
1189 }
1190
1191 // TODO(lukasza): Escape attr_value (&quot; + &amp;).
1192 OnSerializedHtmlFragment(sender, attr_value);
1193 }
1194
1195 SaveItem* SavePackage::FindInProgressSaveItemByFrameTreeNodeID(
1196 int frame_tree_node_id) {
1197 auto it = std::find_if(
1198 in_progress_items_.begin(), in_progress_items_.end(),
1199 [frame_tree_node_id](const SaveUrlItemMap::value_type& v) {
1200 DCHECK(v.second->has_final_name());
1201 return v.second->frame_tree_node_id() == frame_tree_node_id;
1202 });
1203
1204 return (it == in_progress_items_.end()) ? nullptr : it->second;
1205 }
1206
1207 void SavePackage::LogWriteToAlreadyCompletedOrFailedSaveItem(
1208 int frame_tree_node_id) {
1209 auto already_completed_it = std::find_if(
1210 saved_success_items_.begin(), saved_success_items_.end(),
1211 [frame_tree_node_id](const SavedItemMap::value_type& v) {
1212 return v.second->frame_tree_node_id() == frame_tree_node_id;
1213 });
1214 if (already_completed_it != saved_success_items_.end())
1215 wrote_to_completed_file_ = true;
1216
1217 auto failed_it = std::find_if(
1218 saved_failed_items_.begin(), saved_failed_items_.end(),
1219 [frame_tree_node_id](const SaveUrlItemMap::value_type& v) {
1220 DCHECK(v.second->has_final_name());
1221 return v.second->frame_tree_node_id() == frame_tree_node_id;
1222 });
1223 if (failed_it != saved_failed_items_.end())
1224 wrote_to_failed_file_ = true;
1225 }
1226
1173 // Ask for all savable resource links from backend, include main frame and 1227 // Ask for all savable resource links from backend, include main frame and
1174 // sub-frame. 1228 // sub-frame.
1175 void SavePackage::GetSavableResourceLinks() { 1229 void SavePackage::GetSavableResourceLinks() {
1176 if (wait_state_ != START_PROCESS) 1230 if (wait_state_ != START_PROCESS)
1177 return; 1231 return;
1178 1232
1179 wait_state_ = RESOURCES_LIST; 1233 wait_state_ = RESOURCES_LIST;
1180 1234
1181 DCHECK_EQ(0, number_of_frames_pending_response_); 1235 DCHECK_EQ(0, number_of_frames_pending_response_);
1182 web_contents()->ForEachFrame(base::Bind( 1236 web_contents()->ForEachFrame(base::Bind(
(...skipping 16 matching lines...) Expand all
1199 return; 1253 return;
1200 1254
1201 if (resources_list.size() != referrers_list.size()) 1255 if (resources_list.size() != referrers_list.size())
1202 return; 1256 return;
1203 1257
1204 // Add all sub-resources to wait list. 1258 // Add all sub-resources to wait list.
1205 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) { 1259 for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) {
1206 const GURL& u = resources_list[i]; 1260 const GURL& u = resources_list[i];
1207 if (!u.is_valid()) 1261 if (!u.is_valid())
1208 continue; 1262 continue;
1209 if (unique_urls_to_save_.count(u))
1210 continue;
1211 unique_urls_to_save_.insert(u);
1212 1263
1213 SaveFileCreateInfo::SaveFileSource save_source = 1264 SaveItem*& save_item = url_to_save_item_[u];
dcheng 2015/09/30 05:37:32 I think this is a bit too clever =)
Łukasz Anforowicz 2015/10/01 20:39:58 Done. (fixed by assigning to a new invocation of
1214 u.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE 1265 if (save_item == nullptr) {
1215 : SaveFileCreateInfo::SAVE_FILE_FROM_NET; 1266 SaveFileCreateInfo::SaveFileSource save_source =
1216 SaveItem* save_item = new SaveItem(u, referrers_list[i], this, save_source); 1267 u.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE
1268 : SaveFileCreateInfo::SAVE_FILE_FROM_NET;
1269 save_item = new SaveItem(u, this, save_source);
1270 waiting_item_queue_.push(save_item);
1271 }
1272 save_item->set_referrer(referrers_list[i]);
1273 }
1274
1275 // Add the frame to wait list.
1276 SaveItem*& save_item = url_to_save_item_[frame_url];
1277 if (save_item == nullptr) {
1278 save_item =
1279 new SaveItem(frame_url, this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
1217 waiting_item_queue_.push(save_item); 1280 waiting_item_queue_.push(save_item);
1218 } 1281 }
1219 1282 save_item->set_frame_tree_node_id(GetFrameTreeNodeId(sender));
1220 // Store savable frame_url for later processing.
1221 if (frame_url.is_valid())
1222 frame_urls_to_save_.push_back(frame_url);
1223 1283
1224 CompleteSavableResourceLinksResponse(); 1284 CompleteSavableResourceLinksResponse();
1225 } 1285 }
1226 1286
1227 void SavePackage::OnSavableResourceLinksError(RenderFrameHost* sender) { 1287 void SavePackage::OnSavableResourceLinksError(RenderFrameHost* sender) {
1228 CompleteSavableResourceLinksResponse(); 1288 CompleteSavableResourceLinksResponse();
1229 } 1289 }
1230 1290
1231 void SavePackage::CompleteSavableResourceLinksResponse() { 1291 void SavePackage::CompleteSavableResourceLinksResponse() {
1232 --number_of_frames_pending_response_; 1292 --number_of_frames_pending_response_;
1233 DCHECK_LE(0, number_of_frames_pending_response_); 1293 DCHECK_LE(0, number_of_frames_pending_response_);
1234 if (number_of_frames_pending_response_ != 0) 1294 if (number_of_frames_pending_response_ != 0)
1235 return; // Need to wait for more responses from RenderFrames. 1295 return; // Need to wait for more responses from RenderFrames.
1236 1296
1237 // Add frame urls to the waiting_item_queue_. This is done *after* processing
1238 // all savable resource links (i.e. in OnSavableResourceLinksResponse), to
1239 // prefer their referrers in cases where the frame url has already been
1240 // covered by savable resource links.
1241 for (auto& frame_url : frame_urls_to_save_) {
1242 DCHECK(frame_url.is_valid());
1243 if (0 == unique_urls_to_save_.count(frame_url)) {
1244 unique_urls_to_save_.insert(frame_url);
1245 SaveItem* save_item = new SaveItem(
1246 frame_url, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
1247 waiting_item_queue_.push(save_item);
1248 }
1249 }
1250
1251 all_save_items_count_ = static_cast<int>(waiting_item_queue_.size()); 1297 all_save_items_count_ = static_cast<int>(waiting_item_queue_.size());
1252 1298
1253 // We use total bytes as the total number of files we want to save. 1299 // We use total bytes as the total number of files we want to save.
1254 // Hack to avoid touching download_ after user cancel. 1300 // Hack to avoid touching download_ after user cancel.
1255 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem 1301 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem
1256 // with SavePackage flow. 1302 // with SavePackage flow.
1257 if (download_ && (download_->GetState() == DownloadItem::IN_PROGRESS)) 1303 if (download_ && (download_->GetState() == DownloadItem::IN_PROGRESS))
1258 download_->SetTotalBytes(all_save_items_count_); 1304 download_->SetTotalBytes(all_save_items_count_);
1259 1305
1260 if (all_save_items_count_) { 1306 if (all_save_items_count_) {
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 1551
1506 void SavePackage::FinalizeDownloadEntry() { 1552 void SavePackage::FinalizeDownloadEntry() {
1507 DCHECK(download_); 1553 DCHECK(download_);
1508 DCHECK(download_manager_); 1554 DCHECK(download_manager_);
1509 1555
1510 download_manager_->OnSavePackageSuccessfullyFinished(download_); 1556 download_manager_->OnSavePackageSuccessfullyFinished(download_);
1511 StopObservation(); 1557 StopObservation();
1512 } 1558 }
1513 1559
1514 } // namespace content 1560 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/save_package.h ('k') | content/common/frame_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698