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

Side by Side Diff: content/public/test/navigation_simulator.cc

Issue 2698393002: Allow asynchronous deferral in NavigationSimulator (Closed)
Patch Set: Just return the throttle check on Start/Redirect/COmmit Created 3 years, 9 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/public/test/navigation_simulator.h" 5 #include "content/public/test/navigation_simulator.h"
6 6
7 #include "content/browser/frame_host/navigation_handle_impl.h" 7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h"
8 #include "content/browser/frame_host/navigation_request.h" 10 #include "content/browser/frame_host/navigation_request.h"
9 #include "content/common/frame_messages.h" 11 #include "content/common/frame_messages.h"
10 #include "content/public/browser/navigation_throttle.h" 12 #include "content/public/browser/navigation_throttle.h"
11 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/browser_side_navigation_policy.h" 14 #include "content/public/common/browser_side_navigation_policy.h"
13 #include "content/test/test_navigation_url_loader.h" 15 #include "content/test/test_navigation_url_loader.h"
14 #include "content/test/test_render_frame_host.h" 16 #include "content/test/test_render_frame_host.h"
15 #include "net/base/load_flags.h" 17 #include "net/base/load_flags.h"
16 #include "net/url_request/redirect_info.h" 18 #include "net/url_request/redirect_info.h"
17 19
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 56
55 } // namespace 57 } // namespace
56 58
57 // static 59 // static
58 void NavigationSimulator::NavigateAndCommitFromDocument( 60 void NavigationSimulator::NavigateAndCommitFromDocument(
59 const GURL& original_url, 61 const GURL& original_url,
60 RenderFrameHost* render_frame_host) { 62 RenderFrameHost* render_frame_host) {
61 NavigationSimulator simulator( 63 NavigationSimulator simulator(
62 original_url, static_cast<TestRenderFrameHost*>(render_frame_host)); 64 original_url, static_cast<TestRenderFrameHost*>(render_frame_host));
63 simulator.Commit(); 65 simulator.Commit();
66 simulator.WaitForThrottleChecksComplete();
64 } 67 }
65 68
66 // static 69 // static
67 void NavigationSimulator::NavigateAndFailFromDocument( 70 void NavigationSimulator::NavigateAndFailFromDocument(
68 const GURL& original_url, 71 const GURL& original_url,
69 int net_error_code, 72 int net_error_code,
70 RenderFrameHost* render_frame_host) { 73 RenderFrameHost* render_frame_host) {
71 NavigationSimulator simulator( 74 NavigationSimulator simulator(
72 original_url, static_cast<TestRenderFrameHost*>(render_frame_host)); 75 original_url, static_cast<TestRenderFrameHost*>(render_frame_host));
73 simulator.Fail(net_error_code); 76 simulator.Fail(net_error_code);
(...skipping 20 matching lines...) Expand all
94 if (render_frame_host->GetParent()) { 97 if (render_frame_host->GetParent()) {
95 if (!render_frame_host->frame_tree_node()->has_committed_real_load()) 98 if (!render_frame_host->frame_tree_node()->has_committed_real_load())
96 transition_ = ui::PAGE_TRANSITION_AUTO_SUBFRAME; 99 transition_ = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
97 else 100 else
98 transition_ = ui::PAGE_TRANSITION_MANUAL_SUBFRAME; 101 transition_ = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
99 } 102 }
100 } 103 }
101 104
102 NavigationSimulator::~NavigationSimulator() {} 105 NavigationSimulator::~NavigationSimulator() {}
103 106
104 void NavigationSimulator::Start() { 107 NavigationThrottle::ThrottleCheckResult NavigationSimulator::Start() {
105 CHECK(state_ == INITIALIZATION) 108 CHECK(state_ == INITIALIZATION)
106 << "NavigationSimulator::Start should only be called once."; 109 << "NavigationSimulator::Start should only be called once.";
107 state_ = STARTED; 110 state_ = STARTED;
108 111
109 if (IsBrowserSideNavigationEnabled()) { 112 if (IsBrowserSideNavigationEnabled()) {
110 BeginNavigationParams begin_params( 113 BeginNavigationParams begin_params(
111 std::string(), net::LOAD_NORMAL, true /* has_user_gesture */, 114 std::string(), net::LOAD_NORMAL, true /* has_user_gesture */,
112 false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_HYPERLINK, 115 false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_HYPERLINK,
113 blink::WebMixedContentContextType::Blockable, url::Origin()); 116 blink::WebMixedContentContextType::Blockable, url::Origin());
114 CommonNavigationParams common_params; 117 CommonNavigationParams common_params;
115 common_params.url = navigation_url_; 118 common_params.url = navigation_url_;
116 common_params.referrer = referrer_; 119 common_params.referrer = referrer_;
117 common_params.transition = transition_; 120 common_params.transition = transition_;
118 common_params.navigation_type = 121 common_params.navigation_type =
119 PageTransitionCoreTypeIs(transition_, ui::PAGE_TRANSITION_RELOAD) 122 PageTransitionCoreTypeIs(transition_, ui::PAGE_TRANSITION_RELOAD)
120 ? FrameMsg_Navigate_Type::RELOAD 123 ? FrameMsg_Navigate_Type::RELOAD
121 : FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT; 124 : FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
122 render_frame_host_->OnMessageReceived(FrameHostMsg_BeginNavigation( 125 render_frame_host_->OnMessageReceived(FrameHostMsg_BeginNavigation(
123 render_frame_host_->GetRoutingID(), common_params, begin_params)); 126 render_frame_host_->GetRoutingID(), common_params, begin_params));
124 NavigationRequest* request = 127 NavigationRequest* request =
125 render_frame_host_->frame_tree_node()->navigation_request(); 128 render_frame_host_->frame_tree_node()->navigation_request();
126 DCHECK(request); 129 // The request failed synchronously.
130 if (!request)
131 return last_throttle_check_result_.value();
127 DCHECK_EQ(handle_, request->navigation_handle()); 132 DCHECK_EQ(handle_, request->navigation_handle());
128 } else { 133 } else {
129 render_frame_host_->OnMessageReceived( 134 render_frame_host_->OnMessageReceived(
130 FrameHostMsg_DidStartLoading(render_frame_host_->GetRoutingID(), true)); 135 FrameHostMsg_DidStartLoading(render_frame_host_->GetRoutingID(), true));
131 render_frame_host_->OnMessageReceived(FrameHostMsg_DidStartProvisionalLoad( 136 render_frame_host_->OnMessageReceived(FrameHostMsg_DidStartProvisionalLoad(
132 render_frame_host_->GetRoutingID(), navigation_url_, 137 render_frame_host_->GetRoutingID(), navigation_url_,
133 std::vector<GURL>(), base::TimeTicks::Now())); 138 std::vector<GURL>(), base::TimeTicks::Now()));
139 DCHECK(handle_);
134 DCHECK_EQ(handle_, render_frame_host_->navigation_handle()); 140 DCHECK_EQ(handle_, render_frame_host_->navigation_handle());
135 handle_->WillStartRequest( 141 handle_->WillStartRequest(
136 "GET", scoped_refptr<content::ResourceRequestBodyImpl>(), referrer_, 142 "GET", scoped_refptr<content::ResourceRequestBodyImpl>(), referrer_,
137 true /* user_gesture */, transition_, false /* is_external_protocol */, 143 true /* user_gesture */, transition_, false /* is_external_protocol */,
138 REQUEST_CONTEXT_TYPE_LOCATION, 144 REQUEST_CONTEXT_TYPE_LOCATION,
139 blink::WebMixedContentContextType::NotMixedContent, 145 blink::WebMixedContentContextType::NotMixedContent,
140 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>()); 146 GenerateCompleteCallback());
141 } 147 }
142
143 CHECK(handle_); 148 CHECK(handle_);
144 149 return RunOrStoreThrottleCompleteCallback(base::Bind(
145 // Make sure all NavigationThrottles have run. 150 &NavigationSimulator::FinishStart, weak_factory_.GetWeakPtr()));
146 // TODO(clamy): provide a non auto-advance mode if needed.
147 while (handle_->state_for_testing() == NavigationHandleImpl::DEFERRING_START)
148 handle_->Resume();
149
150 CHECK_EQ(1, num_did_start_navigation_called_);
151 CHECK_EQ(1, num_will_start_request_called_);
152 } 151 }
153 152
154 void NavigationSimulator::Redirect(const GURL& new_url) { 153 void NavigationSimulator::FinishStart(
154 NavigationThrottle::ThrottleCheckResult result) {
155 CHECK_EQ(1, num_did_start_navigation_called_);
156 if (result == NavigationThrottle::PROCEED) {
157 CHECK_EQ(1, num_will_start_request_called_);
158 } else {
159 state_ = FAILED;
160 }
161 }
162
163 NavigationThrottle::ThrottleCheckResult NavigationSimulator::Redirect(
164 const GURL& new_url) {
155 CHECK(state_ <= STARTED) << "NavigationSimulator::Redirect should be " 165 CHECK(state_ <= STARTED) << "NavigationSimulator::Redirect should be "
156 "called before Fail or Commit"; 166 "called before Fail or Commit";
157 CHECK_EQ(0, num_did_finish_navigation_called_) 167 CHECK_EQ(0, num_did_finish_navigation_called_)
158 << "NavigationSimulator::Redirect cannot be called after the " 168 << "NavigationSimulator::Redirect cannot be called after the "
159 "navigation has finished"; 169 "navigation has finished";
160 170
161 if (state_ == INITIALIZATION) 171 if (state_ == INITIALIZATION)
162 Start(); 172 StartAndExpectToProceed();
163 173
164 navigation_url_ = new_url; 174 navigation_url_ = new_url;
165 175
166 int previous_num_will_redirect_request_called = 176 int previous_num_will_redirect_request_called =
167 num_will_redirect_request_called_; 177 num_will_redirect_request_called_;
168 int previous_did_redirect_navigation_called = 178 int previous_did_redirect_navigation_called =
169 num_did_redirect_navigation_called_; 179 num_did_redirect_navigation_called_;
170 180
181 last_throttle_check_result_.reset();
171 if (IsBrowserSideNavigationEnabled()) { 182 if (IsBrowserSideNavigationEnabled()) {
172 NavigationRequest* request = 183 NavigationRequest* request =
173 render_frame_host_->frame_tree_node()->navigation_request(); 184 render_frame_host_->frame_tree_node()->navigation_request();
185 request->set_on_checks_complete_callback_for_testing(
186 GenerateCompleteCallback());
174 TestNavigationURLLoader* url_loader = 187 TestNavigationURLLoader* url_loader =
175 static_cast<TestNavigationURLLoader*>(request->loader_for_testing()); 188 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
176 CHECK(url_loader); 189 CHECK(url_loader);
177 190
178 net::RedirectInfo redirect_info; 191 net::RedirectInfo redirect_info;
179 redirect_info.status_code = 302; 192 redirect_info.status_code = 302;
180 redirect_info.new_method = "GET"; 193 redirect_info.new_method = "GET";
181 redirect_info.new_url = new_url; 194 redirect_info.new_url = new_url;
182 redirect_info.new_first_party_for_cookies = new_url; 195 redirect_info.new_first_party_for_cookies = new_url;
183 redirect_info.new_referrer = referrer_.url.spec(); 196 redirect_info.new_referrer = referrer_.url.spec();
184 redirect_info.new_referrer_policy = 197 redirect_info.new_referrer_policy =
185 Referrer::ReferrerPolicyForUrlRequest(referrer_); 198 Referrer::ReferrerPolicyForUrlRequest(referrer_);
186 199
187 url_loader->CallOnRequestRedirected( 200 url_loader->CallOnRequestRedirected(
188 redirect_info, scoped_refptr<ResourceResponse>(new ResourceResponse)); 201 redirect_info, scoped_refptr<ResourceResponse>(new ResourceResponse));
189 } else { 202 } else {
190 handle_->WillRedirectRequest( 203 handle_->WillRedirectRequest(
191 new_url, "GET", referrer_.url, false /* is_external_protocol */, 204 new_url, "GET", referrer_.url, false /* is_external_protocol */,
192 scoped_refptr<net::HttpResponseHeaders>(), 205 scoped_refptr<net::HttpResponseHeaders>(),
193 net::HttpResponseInfo::ConnectionInfo(), 206 net::HttpResponseInfo::ConnectionInfo(), GenerateCompleteCallback());
194 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>());
195 } 207 }
196 208 return RunOrStoreThrottleCompleteCallback(base::Bind(
197 // Make sure all NavigationThrottles have run. 209 &NavigationSimulator::FinishRedirect, weak_factory_.GetWeakPtr(),
198 // TODO(clamy): provide a non auto-advance mode if needed. 210 previous_num_will_redirect_request_called,
199 while (handle_->state_for_testing() == 211 previous_did_redirect_navigation_called));
200 NavigationHandleImpl::DEFERRING_REDIRECT) {
201 handle_->Resume();
202 }
203
204 CHECK_EQ(previous_num_will_redirect_request_called + 1,
205 num_will_redirect_request_called_);
206 CHECK_EQ(previous_did_redirect_navigation_called + 1,
207 num_did_redirect_navigation_called_);
208 } 212 }
209 213
210 void NavigationSimulator::Commit() { 214 void NavigationSimulator::FinishRedirect(
215 int previous_num_will_redirect_request_called,
216 int previous_did_redirect_navigation_called,
217 NavigationThrottle::ThrottleCheckResult result) {
218 if (result == NavigationThrottle::PROCEED) {
219 CHECK_EQ(previous_num_will_redirect_request_called + 1,
220 num_will_redirect_request_called_);
221 CHECK_EQ(previous_did_redirect_navigation_called + 1,
222 num_did_redirect_navigation_called_);
223 } else {
224 state_ = FAILED;
225 }
226 }
227
228 NavigationThrottle::ThrottleCheckResult NavigationSimulator::Commit() {
211 CHECK_LE(state_, STARTED) << "NavigationSimulator::Commit can only be " 229 CHECK_LE(state_, STARTED) << "NavigationSimulator::Commit can only be "
212 "called once, and cannot be called after " 230 "called once, and cannot be called after "
213 "NavigationSimulator::Fail"; 231 "NavigationSimulator::Fail";
214 CHECK_EQ(0, num_did_finish_navigation_called_) 232 CHECK_EQ(0, num_did_finish_navigation_called_)
215 << "NavigationSimulator::Commit cannot be called after the " 233 << "NavigationSimulator::Commit cannot be called after the "
216 "navigation has finished"; 234 "navigation has finished";
217 235
218 if (state_ == INITIALIZATION) 236 if (state_ == INITIALIZATION)
219 Start(); 237 StartAndExpectToProceed();
220 238
221 if (IsBrowserSideNavigationEnabled() && 239 last_throttle_check_result_.reset();
222 render_frame_host_->frame_tree_node()->navigation_request()) { 240 if (IsBrowserSideNavigationEnabled()) {
223 render_frame_host_->PrepareForCommit(); 241 NavigationRequest* request =
242 render_frame_host_->frame_tree_node()->navigation_request();
243 if (request) {
244 request->set_on_checks_complete_callback_for_testing(
245 GenerateCompleteCallback());
246 render_frame_host_->PrepareForCommit();
247 }
224 } 248 }
225 249
226 // Call NavigationHandle::WillProcessResponse if needed. 250 // Call NavigationHandle::WillProcessResponse if needed.
227 if (handle_->state_for_testing() < 251 // Note that the handle's state can be CANCELING if a throttle cancelled it
228 NavigationHandleImpl::WILL_PROCESS_RESPONSE) { 252 // synchronously in PrepareForCommit.
253 if (handle_->state_for_testing() < NavigationHandleImpl::CANCELING) {
229 handle_->WillProcessResponse( 254 handle_->WillProcessResponse(
230 render_frame_host_, scoped_refptr<net::HttpResponseHeaders>(), 255 render_frame_host_, scoped_refptr<net::HttpResponseHeaders>(),
231 net::HttpResponseInfo::ConnectionInfo(), SSLStatus(), GlobalRequestID(), 256 net::HttpResponseInfo::ConnectionInfo(), SSLStatus(), GlobalRequestID(),
232 false /* should_replace_current_entry */, false /* is_download */, 257 false /* should_replace_current_entry */, false /* is_download */,
233 false /* is_stream */, base::Closure(), 258 false /* is_stream */, base::Closure(), GenerateCompleteCallback());
234 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>());
235 } 259 }
260 return RunOrStoreThrottleCompleteCallback(base::Bind(
261 &NavigationSimulator::FinishCommit, weak_factory_.GetWeakPtr()));
262 }
236 263
237 // Make sure all NavigationThrottles have run. 264 void NavigationSimulator::FinishCommit(
238 // TODO(clamy): provide a non auto-advance mode if needed. 265 NavigationThrottle::ThrottleCheckResult result) {
239 while (handle_->state_for_testing() == 266 if (result != NavigationThrottle::PROCEED) {
240 NavigationHandleImpl::DEFERRING_RESPONSE) { 267 state_ = FAILED;
241 handle_->Resume(); 268 return;
242 } 269 }
243
244 CHECK_EQ(1, num_will_process_response_called_); 270 CHECK_EQ(1, num_will_process_response_called_);
245 CHECK_EQ(1, num_ready_to_commit_called_); 271 CHECK_EQ(1, num_ready_to_commit_called_);
246 272
247 // Update the RenderFrameHost now that we know which RenderFrameHost will 273 // Update the RenderFrameHost now that we know which RenderFrameHost will
248 // commit the navigation. 274 // commit the navigation.
249 TestRenderFrameHost* new_render_frame_host = 275 TestRenderFrameHost* new_render_frame_host =
250 static_cast<TestRenderFrameHost*>(handle_->GetRenderFrameHost()); 276 static_cast<TestRenderFrameHost*>(handle_->GetRenderFrameHost());
251 if (!IsBrowserSideNavigationEnabled() && 277 if (!IsBrowserSideNavigationEnabled() &&
252 new_render_frame_host != render_frame_host_) { 278 new_render_frame_host != render_frame_host_) {
253 CHECK(handle_->is_transferring()); 279 CHECK(handle_->is_transferring());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 } 329 }
304 330
305 void NavigationSimulator::Fail(int error_code) { 331 void NavigationSimulator::Fail(int error_code) {
306 CHECK_LE(state_, STARTED) << "NavigationSimulator::Fail can only be " 332 CHECK_LE(state_, STARTED) << "NavigationSimulator::Fail can only be "
307 "called."; 333 "called.";
308 CHECK_EQ(0, num_did_finish_navigation_called_) 334 CHECK_EQ(0, num_did_finish_navigation_called_)
309 << "NavigationSimulator::Fail cannot be called after the " 335 << "NavigationSimulator::Fail cannot be called after the "
310 "navigation has finished"; 336 "navigation has finished";
311 337
312 if (state_ == INITIALIZATION) 338 if (state_ == INITIALIZATION)
313 Start(); 339 StartAndExpectToProceed();
314 340
315 state_ = FAILED; 341 state_ = FAILED;
316 342
317 bool should_result_in_error_page = error_code != net::ERR_ABORTED; 343 bool should_result_in_error_page = error_code != net::ERR_ABORTED;
318 if (IsBrowserSideNavigationEnabled()) { 344 if (IsBrowserSideNavigationEnabled()) {
319 NavigationRequest* request = 345 NavigationRequest* request =
320 render_frame_host_->frame_tree_node()->navigation_request(); 346 render_frame_host_->frame_tree_node()->navigation_request();
321 CHECK(request); 347 CHECK(request);
322 TestNavigationURLLoader* url_loader = 348 TestNavigationURLLoader* url_loader =
323 static_cast<TestNavigationURLLoader*>(request->loader_for_testing()); 349 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 << "The transition cannot be set after the navigation has started"; 465 << "The transition cannot be set after the navigation has started";
440 transition_ = transition; 466 transition_ = transition;
441 } 467 }
442 468
443 void NavigationSimulator::SetReferrer(const Referrer& referrer) { 469 void NavigationSimulator::SetReferrer(const Referrer& referrer) {
444 CHECK_LE(state_, STARTED) << "The referrer cannot be set after the " 470 CHECK_LE(state_, STARTED) << "The referrer cannot be set after the "
445 "navigation has committed or has failed"; 471 "navigation has committed or has failed";
446 referrer_ = referrer; 472 referrer_ = referrer;
447 } 473 }
448 474
475 NavigationThrottle::ThrottleCheckResult
476 NavigationSimulator::WaitForThrottleChecksComplete() {
477 if (!last_throttle_check_result_) {
478 base::RunLoop run_loop;
479 throttle_checks_wait_closure_ = run_loop.QuitClosure();
480 run_loop.Run();
481 throttle_checks_wait_closure_.Reset();
482 }
483 return last_throttle_check_result_.value();
484 }
485
449 void NavigationSimulator::DidStartNavigation( 486 void NavigationSimulator::DidStartNavigation(
450 NavigationHandle* navigation_handle) { 487 NavigationHandle* navigation_handle) {
451 // Check if this navigation is the one we're simulating. 488 // Check if this navigation is the one we're simulating.
452 if (handle_) 489 if (handle_)
453 return; 490 return;
454 491
455 if (navigation_handle->GetURL() != navigation_url_) 492 if (navigation_handle->GetURL() != navigation_url_)
456 return; 493 return;
457 494
458 NavigationHandleImpl* handle = 495 NavigationHandleImpl* handle =
459 static_cast<NavigationHandleImpl*>(navigation_handle); 496 static_cast<NavigationHandleImpl*>(navigation_handle);
460 497
461 if (handle->frame_tree_node() != render_frame_host_->frame_tree_node()) 498 if (handle->frame_tree_node() != render_frame_host_->frame_tree_node())
462 return; 499 return;
463 500
464 handle_ = handle; 501 handle_ = handle;
465 502
466 num_did_start_navigation_called_++; 503 num_did_start_navigation_called_++;
467 504
468 // Add a throttle to count NavigationThrottle calls count. 505 // Add a throttle to count NavigationThrottle calls count.
469 handle->RegisterThrottleForTesting( 506 handle->RegisterThrottleForTesting(
470 base::MakeUnique<NavigationThrottleCallbackRunner>( 507 base::MakeUnique<NavigationThrottleCallbackRunner>(
471 handle, 508 handle,
472 base::Bind(&NavigationSimulator::OnWillStartRequest, 509 base::Bind(&NavigationSimulator::OnWillStartRequest,
473 weak_factory_.GetWeakPtr()), 510 weak_factory_.GetWeakPtr()),
474 base::Bind(&NavigationSimulator::OnWillRedirectRequest, 511 base::Bind(&NavigationSimulator::OnWillRedirectRequest,
475 weak_factory_.GetWeakPtr()), 512 weak_factory_.GetWeakPtr()),
476 base::Bind(&NavigationSimulator::OnWillProcessResponse, 513 base::Bind(&NavigationSimulator::OnWillProcessResponse,
477 weak_factory_.GetWeakPtr()))); 514 weak_factory_.GetWeakPtr())));
515
516 if (IsBrowserSideNavigationEnabled()) {
clamy 2017/03/06 15:22:15 What do you think of the previous suggestion to st
Charlie Harrison 2017/03/06 20:18:43 Done.
517 NavigationRequest* request =
518 render_frame_host_->frame_tree_node()->navigation_request();
519 if (request) {
520 request->set_on_checks_complete_callback_for_testing(
521 GenerateCompleteCallback());
522 }
523 }
478 } 524 }
479 525
480 void NavigationSimulator::DidRedirectNavigation( 526 void NavigationSimulator::DidRedirectNavigation(
481 NavigationHandle* navigation_handle) { 527 NavigationHandle* navigation_handle) {
482 if (navigation_handle == handle_) 528 if (navigation_handle == handle_)
483 num_did_redirect_navigation_called_++; 529 num_did_redirect_navigation_called_++;
484 } 530 }
485 531
486 void NavigationSimulator::ReadyToCommitNavigation( 532 void NavigationSimulator::ReadyToCommitNavigation(
487 NavigationHandle* navigation_handle) { 533 NavigationHandle* navigation_handle) {
(...skipping 12 matching lines...) Expand all
500 } 546 }
501 547
502 void NavigationSimulator::OnWillRedirectRequest() { 548 void NavigationSimulator::OnWillRedirectRequest() {
503 num_will_redirect_request_called_++; 549 num_will_redirect_request_called_++;
504 } 550 }
505 551
506 void NavigationSimulator::OnWillProcessResponse() { 552 void NavigationSimulator::OnWillProcessResponse() {
507 num_will_process_response_called_++; 553 num_will_process_response_called_++;
508 } 554 }
509 555
556 // These methods are a little subtle. Overall, the design constraints are:
557 // 1. Synchronous throttle checks should not cause subsequent
558 // WaitForThrottleChecksComplete to block.
559 //
560 // 2. |complete_callback_| is called after all synchronous code is executed in
561 // response to the throttle checks. This point is important because in some
562 // cases (e.g. cancellation), the OnThrottleChecksComplete callback that the
563 // NavigationRequest/NavigationHandle holds on to will be called before things
564 // like navigation tear down and DidFinishNavigation. This code ensures that
565 // |complete_callback_| is called after that occurs, either synchronously in
566 // RunOrStoreThrottleCompleteCallback, or asynchronously in
567 // OnThrottleChecksComplete.
568 NavigationThrottle::ThrottleCheckResult
569 NavigationSimulator::RunOrStoreThrottleCompleteCallback(
570 ThrottleChecksFinishedCallback finish_callback) {
571 // If completed the checks synchronously, call Finish* here. Else, save the
572 // callback to call asynchronously when the checks finish.
573 if (last_throttle_check_result_) {
574 finish_callback.Run(last_throttle_check_result_.value());
575 return last_throttle_check_result_.value();
576 }
577 complete_callback_ = std::move(finish_callback);
578 return NavigationThrottle::DEFER;
579 }
580
581 void NavigationSimulator::OnThrottleChecksComplete(
582 NavigationThrottle::ThrottleCheckResult result) {
583 // For synchronous throttle checks, set this here, and read from it downstream
584 // in RunOrStoreThrottleCompleteCallback.
585 DCHECK(!last_throttle_check_result_);
586 last_throttle_check_result_ = result;
587 if (!complete_callback_)
588 return;
589 BrowserThread::PostTaskAndReply(
590 BrowserThread::UI, FROM_HERE,
591 base::Bind(std::move(complete_callback_), result),
592 throttle_checks_wait_closure_);
593 }
594
595 ThrottleChecksFinishedCallback NavigationSimulator::GenerateCompleteCallback() {
596 return base::Bind(&NavigationSimulator::OnThrottleChecksComplete,
597 weak_factory_.GetWeakPtr());
598 }
599
600 void NavigationSimulator::StartAndExpectToProceed() {
601 NavigationThrottle::ThrottleCheckResult result = Start();
602 if (result == NavigationThrottle::DEFER)
603 result = WaitForThrottleChecksComplete();
604 CHECK_EQ(NavigationThrottle::PROCEED, result);
605 }
606
510 } // namespace content 607 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698