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

Side by Side Diff: components/dom_distiller/content/browser/dom_distiller_viewer_source.cc

Issue 2353603002: Fix DomDistillerViewerSource to work with PlzNavigate. (Closed)
Patch Set: review comments Created 4 years, 3 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/dom_distiller/content/browser/dom_distiller_viewer_source.h " 5 #include "components/dom_distiller/content/browser/dom_distiller_viewer_source.h "
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 14 matching lines...) Expand all
25 #include "components/dom_distiller/core/dom_distiller_request_view_base.h" 25 #include "components/dom_distiller/core/dom_distiller_request_view_base.h"
26 #include "components/dom_distiller/core/dom_distiller_service.h" 26 #include "components/dom_distiller/core/dom_distiller_service.h"
27 #include "components/dom_distiller/core/experiments.h" 27 #include "components/dom_distiller/core/experiments.h"
28 #include "components/dom_distiller/core/feedback_reporter.h" 28 #include "components/dom_distiller/core/feedback_reporter.h"
29 #include "components/dom_distiller/core/task_tracker.h" 29 #include "components/dom_distiller/core/task_tracker.h"
30 #include "components/dom_distiller/core/url_constants.h" 30 #include "components/dom_distiller/core/url_constants.h"
31 #include "components/dom_distiller/core/url_utils.h" 31 #include "components/dom_distiller/core/url_utils.h"
32 #include "components/dom_distiller/core/viewer.h" 32 #include "components/dom_distiller/core/viewer.h"
33 #include "content/public/browser/navigation_details.h" 33 #include "content/public/browser/navigation_details.h"
34 #include "content/public/browser/navigation_entry.h" 34 #include "content/public/browser/navigation_entry.h"
35 #include "content/public/browser/navigation_handle.h"
35 #include "content/public/browser/render_frame_host.h" 36 #include "content/public/browser/render_frame_host.h"
36 #include "content/public/browser/render_view_host.h" 37 #include "content/public/browser/render_view_host.h"
37 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents.h"
38 #include "content/public/browser/web_contents_observer.h" 39 #include "content/public/browser/web_contents_observer.h"
39 #include "grit/components_strings.h" 40 #include "grit/components_strings.h"
40 #include "mojo/public/cpp/bindings/strong_binding.h" 41 #include "mojo/public/cpp/bindings/strong_binding.h"
41 #include "net/base/url_util.h" 42 #include "net/base/url_util.h"
42 #include "net/url_request/url_request.h" 43 #include "net/url_request/url_request.h"
43 #include "services/shell/public/cpp/interface_provider.h" 44 #include "services/shell/public/cpp/interface_provider.h"
44 #include "services/shell/public/cpp/interface_registry.h" 45 #include "services/shell/public/cpp/interface_registry.h"
45 #include "ui/base/l10n/l10n_util.h" 46 #include "ui/base/l10n/l10n_util.h"
46 47
47 namespace dom_distiller { 48 namespace dom_distiller {
48 49
49 // Handles receiving data asynchronously for a specific entry, and passing 50 // Handles receiving data asynchronously for a specific entry, and passing
50 // it along to the data callback for the data source. Lifetime matches that of 51 // it along to the data callback for the data source. Lifetime matches that of
51 // the current main frame's page in the Viewer instance. 52 // the current main frame's page in the Viewer instance.
52 class DomDistillerViewerSource::RequestViewerHandle 53 class DomDistillerViewerSource::RequestViewerHandle
53 : public DomDistillerRequestViewBase, 54 : public DomDistillerRequestViewBase,
54 public content::WebContentsObserver { 55 public content::WebContentsObserver {
55 public: 56 public:
56 RequestViewerHandle(content::WebContents* web_contents, 57 RequestViewerHandle(content::WebContents* web_contents,
57 const std::string& expected_scheme, 58 const std::string& expected_scheme,
58 const std::string& expected_request_path, 59 const std::string& expected_request_path,
59 DistilledPagePrefs* distilled_page_prefs); 60 DistilledPagePrefs* distilled_page_prefs,
61 DistillerUIHandle* ui_handle);
60 ~RequestViewerHandle() override; 62 ~RequestViewerHandle() override;
61 63
62 // content::WebContentsObserver implementation: 64 // content::WebContentsObserver implementation:
63 void DidNavigateMainFrame( 65 void DidFinishNavigation(
64 const content::LoadCommittedDetails& details, 66 content::NavigationHandle* navigation_handle) override;
65 const content::FrameNavigateParams& params) override;
66 void RenderProcessGone(base::TerminationStatus status) override; 67 void RenderProcessGone(base::TerminationStatus status) override;
67 void WebContentsDestroyed() override; 68 void WebContentsDestroyed() override;
68 void DidFinishLoad(content::RenderFrameHost* render_frame_host, 69 void DidFinishLoad(content::RenderFrameHost* render_frame_host,
69 const GURL& validated_url) override; 70 const GURL& validated_url) override;
70 71
71 private: 72 private:
72 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't 73 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't
73 // ready. 74 // ready.
74 void SendJavaScript(const std::string& buffer) override; 75 void SendJavaScript(const std::string& buffer) override;
75 76
76 // Cancels the current view request. Once called, no updates will be 77 // Cancels the current view request. Once called, no updates will be
77 // propagated to the view, and the request to DomDistillerService will be 78 // propagated to the view, and the request to DomDistillerService will be
78 // cancelled. 79 // cancelled.
79 void Cancel(); 80 void Cancel();
80 81
81 // The scheme hosting the current view request; 82 // The scheme hosting the current view request;
82 std::string expected_scheme_; 83 std::string expected_scheme_;
83 84
84 // The query path for the current view request. 85 // The query path for the current view request.
85 std::string expected_request_path_; 86 std::string expected_request_path_;
86 87
87 // Whether the page is sufficiently initialized to handle updates from the 88 // Whether the page is sufficiently initialized to handle updates from the
88 // distiller. 89 // distiller.
89 bool waiting_for_page_ready_; 90 bool waiting_for_page_ready_;
90 91
91 // Temporary store of pending JavaScript if the page isn't ready to receive 92 // Temporary store of pending JavaScript if the page isn't ready to receive
92 // data from distillation. 93 // data from distillation.
93 std::string buffer_; 94 std::string buffer_;
95
96 // An object for accessing chrome-specific UI controls including external
97 // feedback and opening the distiller settings. Guaranteed to outlive this
98 // object.
99 DistillerUIHandle* distiller_ui_handle_;
94 }; 100 };
95 101
96 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( 102 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
97 content::WebContents* web_contents, 103 content::WebContents* web_contents,
98 const std::string& expected_scheme, 104 const std::string& expected_scheme,
99 const std::string& expected_request_path, 105 const std::string& expected_request_path,
100 DistilledPagePrefs* distilled_page_prefs) 106 DistilledPagePrefs* distilled_page_prefs,
107 DistillerUIHandle* ui_handle)
101 : DomDistillerRequestViewBase(distilled_page_prefs), 108 : DomDistillerRequestViewBase(distilled_page_prefs),
102 expected_scheme_(expected_scheme), 109 expected_scheme_(expected_scheme),
103 expected_request_path_(expected_request_path), 110 expected_request_path_(expected_request_path),
104 waiting_for_page_ready_(true) { 111 waiting_for_page_ready_(true),
112 distiller_ui_handle_(ui_handle) {
105 content::WebContentsObserver::Observe(web_contents); 113 content::WebContentsObserver::Observe(web_contents);
106 distilled_page_prefs_->AddObserver(this); 114 distilled_page_prefs_->AddObserver(this);
107 } 115 }
108 116
109 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { 117 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
110 distilled_page_prefs_->RemoveObserver(this); 118 distilled_page_prefs_->RemoveObserver(this);
111 } 119 }
112 120
113 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript( 121 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript(
114 const std::string& buffer) { 122 const std::string& buffer) {
115 if (waiting_for_page_ready_) { 123 if (waiting_for_page_ready_) {
116 buffer_ += buffer; 124 buffer_ += buffer;
117 } else { 125 } else {
118 DCHECK(buffer_.empty()); 126 DCHECK(buffer_.empty());
119 if (web_contents()) { 127 if (web_contents()) {
120 RunIsolatedJavaScript(web_contents()->GetMainFrame(), buffer); 128 RunIsolatedJavaScript(web_contents()->GetMainFrame(), buffer);
121 } 129 }
122 } 130 }
123 } 131 }
124 132
125 void DomDistillerViewerSource::RequestViewerHandle::DidNavigateMainFrame( 133 void DomDistillerViewerSource::RequestViewerHandle::DidFinishNavigation(
126 const content::LoadCommittedDetails& details, 134 content::NavigationHandle* navigation_handle) {
127 const content::FrameNavigateParams& params) { 135 const GURL& navigation = navigation_handle->GetURL();
128 const GURL& navigation = details.entry->GetURL(); 136 bool expected_main_view_request =
129 if (details.is_in_page || (navigation.SchemeIs(expected_scheme_.c_str()) && 137 navigation.SchemeIs(expected_scheme_.c_str()) &&
130 expected_request_path_ == navigation.query())) { 138 expected_request_path_ == navigation.query();
139 if (navigation_handle->IsSamePage() || expected_main_view_request) {
131 // In-page navigations, as well as the main view request can be ignored. 140 // In-page navigations, as well as the main view request can be ignored.
141 if (expected_main_view_request) {
142 content::RenderFrameHost* render_frame_host =
143 navigation_handle->GetRenderFrameHost();
144 content::RenderViewHost* render_view_host =
145 render_frame_host->GetRenderViewHost();
146 CHECK_EQ(0, render_view_host->GetEnabledBindings());
147
148 // Add mojo service for JavaScript functionality. This is the receiving
149 // end of this particular service.
150 render_frame_host->GetInterfaceRegistry()->AddInterface(
151 base::Bind(&CreateDistillerJavaScriptService,
152 render_frame_host,
153 distiller_ui_handle_));
154
155 // Tell the renderer that this is currently a distilled page.
156 mojom::DistillerPageNotifierServicePtr page_notifier_service;
157 render_frame_host->GetRemoteInterfaces()->GetInterface(
158 &page_notifier_service);
159 DCHECK(page_notifier_service);
160 page_notifier_service->NotifyIsDistillerPage();
161 }
132 return; 162 return;
133 } 163 }
134 164
135 Cancel(); 165 Cancel();
136 } 166 }
137 167
138 void DomDistillerViewerSource::RequestViewerHandle::RenderProcessGone( 168 void DomDistillerViewerSource::RequestViewerHandle::RenderProcessGone(
139 base::TerminationStatus status) { 169 base::TerminationStatus status) {
140 Cancel(); 170 Cancel();
141 } 171 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 dom_distiller_service_(dom_distiller_service), 216 dom_distiller_service_(dom_distiller_service),
187 distiller_ui_handle_(std::move(ui_handle)) {} 217 distiller_ui_handle_(std::move(ui_handle)) {}
188 218
189 DomDistillerViewerSource::~DomDistillerViewerSource() { 219 DomDistillerViewerSource::~DomDistillerViewerSource() {
190 } 220 }
191 221
192 std::string DomDistillerViewerSource::GetSource() const { 222 std::string DomDistillerViewerSource::GetSource() const {
193 return scheme_ + "://"; 223 return scheme_ + "://";
194 } 224 }
195 225
196 void DomDistillerViewerSource::StartDataRequest( 226 void DomDistillerViewerSource::StartDataRequest(
nyquist 2016/09/19 22:26:59 Since you're changing which method we override, sh
jam 2016/09/19 22:43:23 sorry that was a bad merge, this change shouldn't
197 const std::string& path, 227 const std::string& path,
198 int render_process_id, 228 const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
nyquist 2016/09/19 22:27:00 Does this require including content/public/browser
199 int render_frame_id,
200 const content::URLDataSource::GotDataCallback& callback) { 229 const content::URLDataSource::GotDataCallback& callback) {
201 content::RenderFrameHost* render_frame_host = 230 content::WebContents* web_contents = wc_getter.Run();
nyquist 2016/09/19 22:27:00 Are we guaranteed that the info used to create the
jam 2016/09/19 22:43:23 (it's removed in this patch now, but yes it's guar
202 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
203 if (!render_frame_host)
204 return;
205 content::RenderViewHost* render_view_host =
206 render_frame_host->GetRenderViewHost();
207 DCHECK(render_view_host);
208 CHECK_EQ(0, render_view_host->GetEnabledBindings());
209
210 if (kViewerCssPath == path) { 231 if (kViewerCssPath == path) {
211 std::string css = viewer::GetCss(); 232 std::string css = viewer::GetCss();
212 callback.Run(base::RefCountedString::TakeString(&css)); 233 callback.Run(base::RefCountedString::TakeString(&css));
213 return; 234 return;
214 } else if (kViewerLoadingImagePath == path) { 235 } else if (kViewerLoadingImagePath == path) {
215 std::string image = viewer::GetLoadingImage(); 236 std::string image = viewer::GetLoadingImage();
216 callback.Run(base::RefCountedString::TakeString(&image)); 237 callback.Run(base::RefCountedString::TakeString(&image));
217 return; 238 return;
218 } else if (base::StartsWith(path, kViewerSaveFontScalingPath, 239 } else if (base::StartsWith(path, kViewerSaveFontScalingPath,
219 base::CompareCase::SENSITIVE)) { 240 base::CompareCase::SENSITIVE)) {
220 double scale = 1.0; 241 double scale = 1.0;
221 if (base::StringToDouble( 242 if (base::StringToDouble(
222 path.substr(strlen(kViewerSaveFontScalingPath)), &scale)) { 243 path.substr(strlen(kViewerSaveFontScalingPath)), &scale)) {
223 dom_distiller_service_->GetDistilledPagePrefs()->SetFontScaling(scale); 244 dom_distiller_service_->GetDistilledPagePrefs()->SetFontScaling(scale);
224 } 245 }
225 } 246 }
226 content::WebContents* web_contents = 247
227 content::WebContents::FromRenderFrameHost(render_frame_host);
228 DCHECK(web_contents);
229 // An empty |path| is invalid, but guard against it. If not empty, assume 248 // An empty |path| is invalid, but guard against it. If not empty, assume
230 // |path| starts with '?', which is stripped away. 249 // |path| starts with '?', which is stripped away.
231 const std::string path_after_query_separator = 250 const std::string path_after_query_separator =
232 path.size() > 0 ? path.substr(1) : ""; 251 path.size() > 0 ? path.substr(1) : "";
233 RequestViewerHandle* request_viewer_handle = 252 RequestViewerHandle* request_viewer_handle =
234 new RequestViewerHandle(web_contents, scheme_, path_after_query_separator, 253 new RequestViewerHandle(web_contents, scheme_, path_after_query_separator,
235 dom_distiller_service_->GetDistilledPagePrefs()); 254 dom_distiller_service_->GetDistilledPagePrefs(),
255 distiller_ui_handle_);
236 std::unique_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( 256 std::unique_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
237 dom_distiller_service_, path, request_viewer_handle, 257 dom_distiller_service_, path, request_viewer_handle,
238 web_contents->GetContainerBounds().size()); 258 web_contents->GetContainerBounds().size());
239 259
240 GURL current_url(url_utils::GetValueForKeyInUrlPathQuery(path, kUrlKey)); 260 GURL current_url(url_utils::GetValueForKeyInUrlPathQuery(path, kUrlKey));
241 std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml( 261 std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml(
242 url_utils::GetOriginalUrlFromDistillerUrl(current_url).spec(), 262 url_utils::GetOriginalUrlFromDistillerUrl(current_url).spec(),
243 dom_distiller_service_->GetDistilledPagePrefs()->GetTheme(), 263 dom_distiller_service_->GetDistilledPagePrefs()->GetTheme(),
244 dom_distiller_service_->GetDistilledPagePrefs()->GetFontFamily()); 264 dom_distiller_service_->GetDistilledPagePrefs()->GetFontFamily());
245 265
246 // Add mojo service for JavaScript functionality. This is the receiving end
247 // of this particular service.
248 render_frame_host->GetInterfaceRegistry()->AddInterface(
249 base::Bind(&CreateDistillerJavaScriptService,
250 render_frame_host,
251 distiller_ui_handle_.get()));
252
253 // Tell the renderer that this is currently a distilled page.
254 mojom::DistillerPageNotifierServicePtr page_notifier_service;
255 render_frame_host->GetRemoteInterfaces()->GetInterface(
256 &page_notifier_service);
257 DCHECK(page_notifier_service);
258 page_notifier_service->NotifyIsDistillerPage();
259
260 if (viewer_handle) { 266 if (viewer_handle) {
261 // The service returned a |ViewerHandle| and guarantees it will call 267 // The service returned a |ViewerHandle| and guarantees it will call
262 // the |RequestViewerHandle|, so passing ownership to it, to ensure the 268 // the |RequestViewerHandle|, so passing ownership to it, to ensure the
263 // request is not cancelled. The |RequestViewerHandle| will delete itself 269 // request is not cancelled. The |RequestViewerHandle| will delete itself
264 // after receiving the callback. 270 // after receiving the callback.
265 request_viewer_handle->TakeViewerHandle(std::move(viewer_handle)); 271 request_viewer_handle->TakeViewerHandle(std::move(viewer_handle));
266 } else { 272 } else {
267 request_viewer_handle->FlagAsErrorPage(); 273 request_viewer_handle->FlagAsErrorPage();
268 } 274 }
269 275
(...skipping 25 matching lines...) Expand all
295 std::string DomDistillerViewerSource::GetContentSecurityPolicyStyleSrc() 301 std::string DomDistillerViewerSource::GetContentSecurityPolicyStyleSrc()
296 const { 302 const {
297 return "style-src 'self' https://fonts.googleapis.com;"; 303 return "style-src 'self' https://fonts.googleapis.com;";
298 } 304 }
299 305
300 std::string DomDistillerViewerSource::GetContentSecurityPolicyChildSrc() const { 306 std::string DomDistillerViewerSource::GetContentSecurityPolicyChildSrc() const {
301 return "child-src *;"; 307 return "child-src *;";
302 } 308 }
303 309
304 } // namespace dom_distiller 310 } // namespace dom_distiller
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698