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

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

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

Powered by Google App Engine
This is Rietveld 408576698