OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/navigation_interception/intercept_navigation_throttle.h" | 5 #include "components/navigation_interception/intercept_navigation_throttle.h" |
6 | 6 |
7 #include "components/navigation_interception/navigation_params.h" | 7 #include "components/navigation_interception/navigation_params.h" |
8 #include "content/public/browser/browser_thread.h" | 8 #include "content/public/browser/browser_thread.h" |
9 #include "content/public/browser/navigation_handle.h" | 9 #include "content/public/browser/navigation_handle.h" |
10 | 10 |
11 using content::BrowserThread; | 11 using content::BrowserThread; |
12 | 12 |
13 namespace navigation_interception { | 13 namespace navigation_interception { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 using ChecksPerformedCallback = base::Callback<void(bool)>; | 17 using ChecksPerformedCallback = base::Callback<void(bool, bool)>; |
18 | 18 |
19 // This is used to run |should_ignore_callback| if it can destroy the | 19 // This is used to run |should_ignore_callback| if it can destroy the |
20 // WebContents (and the InterceptNavigationThrottle along). In that case, | 20 // WebContents (and the InterceptNavigationThrottle along). In that case, |
21 // |on_checks_performed_callback| will be a no-op. | 21 // |on_checks_performed_callback| will be a no-op. |
22 void RunCallback( | 22 void RunCallback( |
23 content::WebContents* web_contents, | 23 content::WebContents* web_contents, |
24 const NavigationParams& navigation_params, | 24 const NavigationParams& navigation_params, |
25 InterceptNavigationThrottle::CheckCallback should_ignore_callback, | 25 InterceptNavigationThrottle::CheckCallback should_ignore_callback, |
26 ChecksPerformedCallback on_checks_performed_callback) { | 26 ChecksPerformedCallback on_checks_performed_callback, |
| 27 base::WeakPtr<InterceptNavigationThrottle> throttle) { |
27 bool should_ignore_navigation = | 28 bool should_ignore_navigation = |
28 should_ignore_callback.Run(web_contents, navigation_params); | 29 should_ignore_callback.Run(web_contents, navigation_params); |
29 | 30 |
30 // If the InterceptNavigationThrottle that called RunCallback is still alive | 31 // If the InterceptNavigationThrottle that called RunCallback is still alive |
31 // after |should_ignore_callback| has run, this will run | 32 // after |should_ignore_callback| has run, this will run |
32 // InterceptNavigationThrottle::OnAsynchronousChecksPerformed. | 33 // InterceptNavigationThrottle::OnAsynchronousChecksPerformed. |
33 on_checks_performed_callback.Run(should_ignore_navigation); | 34 // TODO(clamy): remove this boolean after crbug.com/570200 is fixed. |
| 35 bool throttle_was_destroyed = !throttle.get(); |
| 36 on_checks_performed_callback.Run(should_ignore_navigation, |
| 37 throttle_was_destroyed); |
34 } | 38 } |
35 | 39 |
36 } // namespace | 40 } // namespace |
37 | 41 |
38 InterceptNavigationThrottle::InterceptNavigationThrottle( | 42 InterceptNavigationThrottle::InterceptNavigationThrottle( |
39 content::NavigationHandle* navigation_handle, | 43 content::NavigationHandle* navigation_handle, |
40 CheckCallback should_ignore_callback, | 44 CheckCallback should_ignore_callback, |
41 bool run_callback_synchronously) | 45 bool run_callback_synchronously) |
42 : content::NavigationThrottle(navigation_handle), | 46 : content::NavigationThrottle(navigation_handle), |
43 should_ignore_callback_(should_ignore_callback), | 47 should_ignore_callback_(should_ignore_callback), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 void InterceptNavigationThrottle::RunCallbackAsynchronously( | 94 void InterceptNavigationThrottle::RunCallbackAsynchronously( |
91 const NavigationParams& navigation_params) { | 95 const NavigationParams& navigation_params) { |
92 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 96 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
93 | 97 |
94 // Run the callback in a helper function as it may lead ot the destruction of | 98 // Run the callback in a helper function as it may lead ot the destruction of |
95 // this InterceptNavigationThrottle. | 99 // this InterceptNavigationThrottle. |
96 RunCallback( | 100 RunCallback( |
97 navigation_handle()->GetWebContents(), navigation_params, | 101 navigation_handle()->GetWebContents(), navigation_params, |
98 should_ignore_callback_, | 102 should_ignore_callback_, |
99 base::Bind(&InterceptNavigationThrottle::OnAsynchronousChecksPerformed, | 103 base::Bind(&InterceptNavigationThrottle::OnAsynchronousChecksPerformed, |
100 weak_factory_.GetWeakPtr())); | 104 weak_factory_.GetWeakPtr()), |
| 105 weak_factory_.GetWeakPtr()); |
101 | 106 |
102 // DO NOT ADD CODE AFTER HERE: at this point the InterceptNavigationThrottle | 107 // DO NOT ADD CODE AFTER HERE: at this point the InterceptNavigationThrottle |
103 // may have been destroyed by the |should_ignore_callback_|. Adding code here | 108 // may have been destroyed by the |should_ignore_callback_|. Adding code here |
104 // will cause use-after-free bugs. | 109 // will cause use-after-free bugs. |
105 // | 110 // |
106 // Code that needs to act on the result of the |should_ignore_callback_| | 111 // Code that needs to act on the result of the |should_ignore_callback_| |
107 // should be put inside OnAsynchronousChecksPerformed. This function will be | 112 // should be put inside OnAsynchronousChecksPerformed. This function will be |
108 // called after |should_ignore_callback_| has run, if this | 113 // called after |should_ignore_callback_| has run, if this |
109 // InterceptNavigationThrottle is still alive. | 114 // InterceptNavigationThrottle is still alive. |
110 } | 115 } |
111 | 116 |
112 void InterceptNavigationThrottle::OnAsynchronousChecksPerformed( | 117 void InterceptNavigationThrottle::OnAsynchronousChecksPerformed( |
113 bool should_ignore_navigation) { | 118 bool should_ignore_navigation, |
| 119 bool throttle_was_destroyed) { |
| 120 CHECK(!throttle_was_destroyed); |
| 121 content::NavigationHandle* handle = navigation_handle(); |
| 122 CHECK(handle); |
114 if (should_ignore_navigation) { | 123 if (should_ignore_navigation) { |
115 navigation_handle()->CancelDeferredNavigation( | 124 navigation_handle()->CancelDeferredNavigation( |
116 content::NavigationThrottle::CANCEL_AND_IGNORE); | 125 content::NavigationThrottle::CANCEL_AND_IGNORE); |
117 } else { | 126 } else { |
118 navigation_handle()->Resume(); | 127 handle->Resume(); |
119 } | 128 } |
120 } | 129 } |
121 | 130 |
122 } // namespace navigation_interception | 131 } // namespace navigation_interception |
OLD | NEW |