| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 6 #include "base/strings/utf_string_conversions.h" | 6 #include "base/strings/utf_string_conversions.h" |
| 7 #include "content/browser/frame_host/cross_site_transferring_request.h" | 7 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 8 #include "content/browser/frame_host/navigation_controller_impl.h" | 8 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 9 #include "content/browser/frame_host/navigation_entry_impl.h" | 9 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 10 #include "content/browser/frame_host/navigator.h" | 10 #include "content/browser/frame_host/navigator.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 117 } |
| 118 | 118 |
| 119 private: | 119 private: |
| 120 int process_id_; | 120 int process_id_; |
| 121 int routing_id_; | 121 int routing_id_; |
| 122 bool deleted_; | 122 bool deleted_; |
| 123 | 123 |
| 124 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDeletedObserver); | 124 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDeletedObserver); |
| 125 }; | 125 }; |
| 126 | 126 |
| 127 | 127 // This observer keeps track of the last deleted RenderFrameHost to avoid |
| 128 // This observer keeps track of the last deleted RenderViewHost to avoid | |
| 129 // accessing it and causing use-after-free condition. | 128 // accessing it and causing use-after-free condition. |
| 130 class RenderFrameHostDeletedObserver : public WebContentsObserver { | 129 class RenderFrameHostDeletedObserver : public WebContentsObserver { |
| 131 public: | 130 public: |
| 132 RenderFrameHostDeletedObserver(RenderFrameHost* rfh) | 131 RenderFrameHostDeletedObserver(RenderFrameHost* rfh) |
| 133 : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), | 132 : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), |
| 134 process_id_(rfh->GetProcess()->GetID()), | 133 process_id_(rfh->GetProcess()->GetID()), |
| 135 routing_id_(rfh->GetRoutingID()), | 134 routing_id_(rfh->GetRoutingID()), |
| 136 deleted_(false) { | 135 deleted_(false) { |
| 137 } | 136 } |
| 138 | 137 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 return favicon_received_; | 185 return favicon_received_; |
| 187 } | 186 } |
| 188 | 187 |
| 189 private: | 188 private: |
| 190 bool plugin_crashed_; | 189 bool plugin_crashed_; |
| 191 bool favicon_received_; | 190 bool favicon_received_; |
| 192 | 191 |
| 193 DISALLOW_COPY_AND_ASSIGN(PluginFaviconMessageObserver); | 192 DISALLOW_COPY_AND_ASSIGN(PluginFaviconMessageObserver); |
| 194 }; | 193 }; |
| 195 | 194 |
| 195 // Ensures that RenderFrameDeleted and RenderFrameCreated are called in a |
| 196 // consistent manner. |
| 197 class FrameLifetimeConsistencyChecker : public WebContentsObserver { |
| 198 public: |
| 199 explicit FrameLifetimeConsistencyChecker(WebContentsImpl* web_contents) |
| 200 : WebContentsObserver(web_contents) { |
| 201 RenderViewCreated(web_contents->GetRenderViewHost()); |
| 202 RenderFrameCreated(web_contents->GetMainFrame()); |
| 203 } |
| 204 |
| 205 virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE { |
| 206 std::pair<int, int> routing_pair = |
| 207 std::make_pair(render_frame_host->GetProcess()->GetID(), |
| 208 render_frame_host->GetRoutingID()); |
| 209 bool was_live_already = !live_routes_.insert(routing_pair).second; |
| 210 bool was_used_before = deleted_routes_.count(routing_pair) != 0; |
| 211 |
| 212 if (was_live_already) { |
| 213 FAIL() << "RenderFrameCreated called more than once for routing pair: " |
| 214 << Format(render_frame_host); |
| 215 } else if (was_used_before) { |
| 216 FAIL() << "RenderFrameCreated called for routing pair " |
| 217 << Format(render_frame_host) << " that was previously deleted."; |
| 218 } |
| 219 } |
| 220 |
| 221 virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE { |
| 222 std::pair<int, int> routing_pair = |
| 223 std::make_pair(render_frame_host->GetProcess()->GetID(), |
| 224 render_frame_host->GetRoutingID()); |
| 225 bool was_live = live_routes_.erase(routing_pair); |
| 226 bool was_dead_already = !deleted_routes_.insert(routing_pair).second; |
| 227 |
| 228 if (was_dead_already) { |
| 229 FAIL() << "RenderFrameDeleted called more than once for routing pair " |
| 230 << Format(render_frame_host); |
| 231 } else if (!was_live) { |
| 232 FAIL() << "RenderFrameDeleted called for routing pair " |
| 233 << Format(render_frame_host) |
| 234 << " for which RenderFrameCreated was never called"; |
| 235 } |
| 236 } |
| 237 |
| 238 private: |
| 239 std::string Format(RenderFrameHost* render_frame_host) { |
| 240 return base::StringPrintf( |
| 241 "(%d, %d -> %s )", |
| 242 render_frame_host->GetProcess()->GetID(), |
| 243 render_frame_host->GetRoutingID(), |
| 244 render_frame_host->GetSiteInstance()->GetSiteURL().spec().c_str()); |
| 245 } |
| 246 std::set<std::pair<int, int> > live_routes_; |
| 247 std::set<std::pair<int, int> > deleted_routes_; |
| 248 }; |
| 196 | 249 |
| 197 } // namespace | 250 } // namespace |
| 198 | 251 |
| 199 class RenderFrameHostManagerTest | 252 class RenderFrameHostManagerTest |
| 200 : public RenderViewHostImplTestHarness { | 253 : public RenderViewHostImplTestHarness { |
| 201 public: | 254 public: |
| 202 virtual void SetUp() OVERRIDE { | 255 virtual void SetUp() OVERRIDE { |
| 203 RenderViewHostImplTestHarness::SetUp(); | 256 RenderViewHostImplTestHarness::SetUp(); |
| 204 WebUIControllerFactory::RegisterFactory(&factory_); | 257 WebUIControllerFactory::RegisterFactory(&factory_); |
| 258 lifetime_checker_.reset(new FrameLifetimeConsistencyChecker(contents())); |
| 205 } | 259 } |
| 206 | 260 |
| 207 virtual void TearDown() OVERRIDE { | 261 virtual void TearDown() OVERRIDE { |
| 262 lifetime_checker_.reset(); |
| 208 RenderViewHostImplTestHarness::TearDown(); | 263 RenderViewHostImplTestHarness::TearDown(); |
| 209 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); | 264 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); |
| 210 } | 265 } |
| 211 | 266 |
| 212 void set_should_create_webui(bool should_create_webui) { | 267 void set_should_create_webui(bool should_create_webui) { |
| 213 factory_.set_should_create_webui(should_create_webui); | 268 factory_.set_should_create_webui(should_create_webui); |
| 214 } | 269 } |
| 215 | 270 |
| 216 void StartCrossSiteTransition(TestWebContents* contents) { | 271 void StartCrossSiteTransition(TestWebContents* contents) { |
| 217 std::vector<GURL> url_chain; | 272 std::vector<GURL> url_chain; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 358 |
| 304 dest_rvh->SendNavigate(101, kDestUrl); | 359 dest_rvh->SendNavigate(101, kDestUrl); |
| 305 ntp_rvh->OnSwappedOut(false); | 360 ntp_rvh->OnSwappedOut(false); |
| 306 | 361 |
| 307 EXPECT_TRUE(ntp_rvh->IsSwappedOut()); | 362 EXPECT_TRUE(ntp_rvh->IsSwappedOut()); |
| 308 return ntp_rvh; | 363 return ntp_rvh; |
| 309 } | 364 } |
| 310 | 365 |
| 311 private: | 366 private: |
| 312 RenderFrameHostManagerTestWebUIControllerFactory factory_; | 367 RenderFrameHostManagerTestWebUIControllerFactory factory_; |
| 368 scoped_ptr<FrameLifetimeConsistencyChecker> lifetime_checker_; |
| 313 }; | 369 }; |
| 314 | 370 |
| 315 // Tests that when you navigate from a chrome:// url to another page, and | 371 // Tests that when you navigate from a chrome:// url to another page, and |
| 316 // then do that same thing in another tab, that the two resulting pages have | 372 // then do that same thing in another tab, that the two resulting pages have |
| 317 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is | 373 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is |
| 318 // a regression test for bug 9364. | 374 // a regression test for bug 9364. |
| 319 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { | 375 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { |
| 320 set_should_create_webui(true); | 376 set_should_create_webui(true); |
| 321 const GURL kChromeUrl("chrome://foo"); | 377 const GURL kChromeUrl("chrome://foo"); |
| 322 const GURL kDestUrl("http://www.google.com/"); | 378 const GURL kDestUrl("http://www.google.com/"); |
| (...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 pending_rfh->GetSiteInstance())->increment_active_view_count(); | 1838 pending_rfh->GetSiteInstance())->increment_active_view_count(); |
| 1783 | 1839 |
| 1784 main_test_rfh()->OnMessageReceived( | 1840 main_test_rfh()->OnMessageReceived( |
| 1785 FrameHostMsg_BeforeUnload_ACK(0, false, now, now)); | 1841 FrameHostMsg_BeforeUnload_ACK(0, false, now, now)); |
| 1786 EXPECT_FALSE(contents()->cross_navigation_pending()); | 1842 EXPECT_FALSE(contents()->cross_navigation_pending()); |
| 1787 EXPECT_FALSE(rvh_deleted_observer.deleted()); | 1843 EXPECT_FALSE(rvh_deleted_observer.deleted()); |
| 1788 } | 1844 } |
| 1789 } | 1845 } |
| 1790 | 1846 |
| 1791 } // namespace content | 1847 } // namespace content |
| OLD | NEW |