Chromium Code Reviews| 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/strings/utf_string_conversions.h" | 6 #include "base/strings/utf_string_conversions.h" |
| 6 #include "content/browser/frame_host/cross_site_transferring_request.h" | 7 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 7 #include "content/browser/frame_host/navigation_controller_impl.h" | 8 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 8 #include "content/browser/frame_host/navigation_entry_impl.h" | 9 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 9 #include "content/browser/frame_host/navigator.h" | 10 #include "content/browser/frame_host/navigator.h" |
| 10 #include "content/browser/frame_host/render_frame_host_manager.h" | 11 #include "content/browser/frame_host/render_frame_host_manager.h" |
| 11 #include "content/browser/site_instance_impl.h" | 12 #include "content/browser/site_instance_impl.h" |
| 12 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 13 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 13 #include "content/common/frame_messages.h" | 14 #include "content/common/frame_messages.h" |
| 14 #include "content/common/view_messages.h" | 15 #include "content/common/view_messages.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 virtual void BeforeUnloadFired(WebContents* web_contents, | 87 virtual void BeforeUnloadFired(WebContents* web_contents, |
| 87 bool proceed, | 88 bool proceed, |
| 88 bool* proceed_to_fire_unload) OVERRIDE { | 89 bool* proceed_to_fire_unload) OVERRIDE { |
| 89 *proceed_to_fire_unload = proceed; | 90 *proceed_to_fire_unload = proceed; |
| 90 } | 91 } |
| 91 | 92 |
| 92 private: | 93 private: |
| 93 DISALLOW_COPY_AND_ASSIGN(BeforeUnloadFiredWebContentsDelegate); | 94 DISALLOW_COPY_AND_ASSIGN(BeforeUnloadFiredWebContentsDelegate); |
| 94 }; | 95 }; |
| 95 | 96 |
| 97 // This observer keeps track of the last deleted RenderViewHost to avoid | |
| 98 // accessing it and causing use-after-free condition. | |
| 99 class RenderViewHostDeletedObserver : public WebContentsObserver { | |
| 100 public: | |
| 101 RenderViewHostDeletedObserver(WebContents* web_contents) | |
| 102 : WebContentsObserver(web_contents), | |
| 103 last_deleted_(NULL) {} | |
| 104 | |
| 105 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE { | |
| 106 last_deleted_ = render_view_host; | |
| 107 } | |
| 108 | |
| 109 RenderViewHost* last_deleted() { | |
| 110 return last_deleted_; | |
| 111 } | |
| 112 | |
| 113 private: | |
| 114 RenderViewHost* last_deleted_; | |
| 115 | |
| 116 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDeletedObserver); | |
| 117 }; | |
| 118 | |
| 119 | |
| 120 // This observer is used to check whether IPC messages are being filtered for | |
| 121 // swapped out RenderFrameHost objects. It observes the plugin crash and favicon | |
| 122 // update events, which the FilterMessagesWhileSwappedOut test simulates being | |
| 123 // sent. The test is successful if the event is not observed. | |
| 124 // See http://crbug.com/351815 | |
| 125 class IpcMessageObserver : public WebContentsObserver { | |
|
Charlie Reis
2014/03/21 21:35:13
This sounds like it's more general than just plugi
nasko
2014/03/24 17:48:11
Done.
| |
| 126 public: | |
| 127 IpcMessageObserver(WebContents* web_contents) | |
| 128 : WebContentsObserver(web_contents), | |
| 129 plugin_crashed_(false), | |
| 130 favicon_received_(false) { } | |
| 131 | |
| 132 virtual void PluginCrashed(const base::FilePath& plugin_path, | |
| 133 base::ProcessId plugin_pid) OVERRIDE { | |
| 134 plugin_crashed_ = true; | |
| 135 } | |
| 136 | |
| 137 virtual void DidUpdateFaviconURL( | |
| 138 int32 page_id, | |
| 139 const std::vector<FaviconURL>& candidates) OVERRIDE { | |
| 140 favicon_received_ = true; | |
| 141 } | |
| 142 | |
| 143 bool plugin_crashed() { | |
| 144 return plugin_crashed_; | |
| 145 } | |
| 146 | |
| 147 bool favicon_received() { | |
| 148 return favicon_received_; | |
| 149 } | |
| 150 | |
| 151 private: | |
| 152 bool plugin_crashed_; | |
| 153 bool favicon_received_; | |
| 154 | |
| 155 DISALLOW_COPY_AND_ASSIGN(IpcMessageObserver); | |
| 156 }; | |
| 157 | |
| 158 | |
| 96 } // namespace | 159 } // namespace |
| 97 | 160 |
| 98 class RenderFrameHostManagerTest | 161 class RenderFrameHostManagerTest |
| 99 : public RenderViewHostImplTestHarness { | 162 : public RenderViewHostImplTestHarness { |
| 100 public: | 163 public: |
| 101 virtual void SetUp() OVERRIDE { | 164 virtual void SetUp() OVERRIDE { |
| 102 RenderViewHostImplTestHarness::SetUp(); | 165 RenderViewHostImplTestHarness::SetUp(); |
| 103 WebUIControllerFactory::RegisterFactory(&factory_); | 166 WebUIControllerFactory::RegisterFactory(&factory_); |
| 104 } | 167 } |
| 105 | 168 |
| 106 virtual void TearDown() OVERRIDE { | 169 virtual void TearDown() OVERRIDE { |
| 107 RenderViewHostImplTestHarness::TearDown(); | 170 RenderViewHostImplTestHarness::TearDown(); |
| 108 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); | 171 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); |
| 109 } | 172 } |
| 110 | 173 |
| 111 void set_should_create_webui(bool should_create_webui) { | 174 void set_should_create_webui(bool should_create_webui) { |
| 112 factory_.set_should_create_webui(should_create_webui); | 175 factory_.set_should_create_webui(should_create_webui); |
| 113 } | 176 } |
| 114 | 177 |
| 178 void StartCrossSiteTransition(TestWebContents* contents) { | |
|
Charlie Reis
2014/03/21 21:35:13
Great, I'm a big fan of making most of the tests u
nasko
2014/03/24 17:48:11
Does the NavigateWithEarlyReNavigation test case c
Charlie Reis
2014/03/24 20:38:02
Actually, that appears to be one of the few tests
| |
| 179 std::vector<GURL> url_chain; | |
| 180 url_chain.push_back(GURL()); | |
| 181 contents->GetRenderManagerForTesting()->OnCrossSiteResponse( | |
| 182 contents->GetRenderManagerForTesting()->pending_frame_host(), | |
| 183 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(), | |
| 184 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false); | |
| 185 EXPECT_TRUE(contents->cross_navigation_pending()); | |
| 186 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( | |
| 187 contents->GetRenderViewHost()); | |
| 188 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK, | |
|
Charlie Reis
2014/03/21 21:35:13
Great, glad to see these sorts of checks.
nasko
2014/03/24 17:48:11
Done.
| |
| 189 rvh->rvh_state()); | |
| 190 } | |
| 191 | |
| 115 void NavigateActiveAndCommit(const GURL& url) { | 192 void NavigateActiveAndCommit(const GURL& url) { |
| 116 // Note: we navigate the active RenderViewHost because previous navigations | 193 // Note: we navigate the active RenderViewHost because previous navigations |
| 117 // won't have committed yet, so NavigateAndCommit does the wrong thing | 194 // won't have committed yet, so NavigateAndCommit does the wrong thing |
| 118 // for us. | 195 // for us. |
| 119 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string()); | 196 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string()); |
| 120 TestRenderViewHost* old_rvh = test_rvh(); | 197 TestRenderViewHost* old_rvh = test_rvh(); |
| 121 | 198 |
| 122 // Simulate the BeforeUnload_ACK that is received from the current renderer | 199 // Simulate the BeforeUnload_ACK that is received from the current renderer |
| 123 // for a cross-site navigation. | 200 // for a cross-site navigation. |
| 124 if (old_rvh != active_rvh()) | 201 if (old_rvh != active_rvh()) { |
| 125 old_rvh->SendBeforeUnloadACK(true); | 202 old_rvh->SendBeforeUnloadACK(true); |
| 203 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, old_rvh->rvh_state()); | |
| 204 } | |
| 126 | 205 |
| 127 // Commit the navigation with a new page ID. | 206 // Commit the navigation with a new page ID. |
| 128 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( | 207 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( |
| 129 active_rvh()->GetSiteInstance()); | 208 active_rvh()->GetSiteInstance()); |
| 130 | 209 |
| 210 // Simulate the response comming from the pending renderer. | |
| 211 if (old_rvh != active_rvh()) | |
| 212 StartCrossSiteTransition(contents()); | |
| 213 | |
| 131 // Simulate the SwapOut_ACK that fires if you commit a cross-site | 214 // Simulate the SwapOut_ACK that fires if you commit a cross-site |
| 132 // navigation. | 215 // navigation. |
| 133 if (old_rvh != active_rvh()) | 216 if (old_rvh != active_rvh()) { |
| 134 old_rvh->OnSwappedOut(false); | 217 old_rvh->OnSwappedOut(false); |
| 218 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, | |
| 219 old_rvh->rvh_state()); | |
| 220 } | |
| 135 | 221 |
| 222 // Use an observer to avoid accessing a deleted renderer later on when the | |
| 223 // state is being checked. | |
| 224 RenderViewHostDeletedObserver rvh_observer(contents()); | |
|
Charlie Reis
2014/03/21 21:35:13
I'm not thrilled with keeping the pointer to a del
nasko
2014/03/24 17:48:11
Done.
| |
| 136 active_test_rvh()->SendNavigate(max_page_id + 1, url); | 225 active_test_rvh()->SendNavigate(max_page_id + 1, url); |
| 226 | |
| 227 if (old_rvh != active_rvh() && old_rvh != rvh_observer.last_deleted()) | |
| 228 EXPECT_TRUE(old_rvh->IsSwappedOut()); | |
| 137 } | 229 } |
| 138 | 230 |
| 139 bool ShouldSwapProcesses(RenderFrameHostManager* manager, | 231 bool ShouldSwapProcesses(RenderFrameHostManager* manager, |
| 140 const NavigationEntryImpl* current_entry, | 232 const NavigationEntryImpl* current_entry, |
| 141 const NavigationEntryImpl* new_entry) const { | 233 const NavigationEntryImpl* new_entry) const { |
| 142 return manager->ShouldSwapBrowsingInstancesForNavigation(current_entry, | 234 return manager->ShouldSwapBrowsingInstancesForNavigation(current_entry, |
| 143 new_entry); | 235 new_entry); |
| 144 } | 236 } |
| 145 | 237 |
| 146 // Creates a test RenderViewHost that's swapped out. | 238 // Creates a test RenderViewHost that's swapped out. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 // The second one is the opposite, creating a cross-site transition and | 307 // The second one is the opposite, creating a cross-site transition and |
| 216 // requiring a beforeunload ack. | 308 // requiring a beforeunload ack. |
| 217 contents2->GetController().LoadURL( | 309 contents2->GetController().LoadURL( |
| 218 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); | 310 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); |
| 219 EXPECT_TRUE(contents2->cross_navigation_pending()); | 311 EXPECT_TRUE(contents2->cross_navigation_pending()); |
| 220 TestRenderViewHost* dest_rvh2 = static_cast<TestRenderViewHost*>( | 312 TestRenderViewHost* dest_rvh2 = static_cast<TestRenderViewHost*>( |
| 221 contents2->GetRenderManagerForTesting()->pending_render_view_host()); | 313 contents2->GetRenderManagerForTesting()->pending_render_view_host()); |
| 222 ASSERT_TRUE(dest_rvh2); | 314 ASSERT_TRUE(dest_rvh2); |
| 223 | 315 |
| 224 ntp_rvh2->SendBeforeUnloadACK(true); | 316 ntp_rvh2->SendBeforeUnloadACK(true); |
| 225 ntp_rvh2->OnSwappedOut(false); | 317 StartCrossSiteTransition(contents2.get()); |
| 226 dest_rvh2->SendNavigate(101, kDestUrl); | 318 dest_rvh2->SendNavigate(101, kDestUrl); |
| 227 | 319 |
| 228 // The two RVH's should be different in every way. | 320 // The two RVH's should be different in every way. |
| 229 EXPECT_NE(active_rvh()->GetProcess(), dest_rvh2->GetProcess()); | 321 EXPECT_NE(active_rvh()->GetProcess(), dest_rvh2->GetProcess()); |
| 230 EXPECT_NE(active_rvh()->GetSiteInstance(), dest_rvh2->GetSiteInstance()); | 322 EXPECT_NE(active_rvh()->GetSiteInstance(), dest_rvh2->GetSiteInstance()); |
| 231 EXPECT_FALSE(active_rvh()->GetSiteInstance()->IsRelatedSiteInstance( | 323 EXPECT_FALSE(active_rvh()->GetSiteInstance()->IsRelatedSiteInstance( |
| 232 dest_rvh2->GetSiteInstance())); | 324 dest_rvh2->GetSiteInstance())); |
| 233 | 325 |
| 234 // Navigate both to the new tab page, and verify that they share a | 326 // Navigate both to the new tab page, and verify that they share a |
| 235 // RenderProcessHost (not a SiteInstance). | 327 // RenderProcessHost (not a SiteInstance). |
| 236 NavigateActiveAndCommit(kChromeUrl); | 328 NavigateActiveAndCommit(kChromeUrl); |
| 237 | 329 |
| 238 contents2->GetController().LoadURL( | 330 contents2->GetController().LoadURL( |
| 239 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); | 331 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); |
| 240 dest_rvh2->SendBeforeUnloadACK(true); | 332 dest_rvh2->SendBeforeUnloadACK(true); |
| 241 dest_rvh2->OnSwappedOut(false); | 333 StartCrossSiteTransition(contents2.get()); |
| 242 static_cast<TestRenderViewHost*>(contents2->GetRenderManagerForTesting()-> | 334 static_cast<TestRenderViewHost*>(contents2->GetRenderManagerForTesting()-> |
| 243 pending_render_view_host())->SendNavigate(102, kChromeUrl); | 335 pending_render_view_host())->SendNavigate(102, kChromeUrl); |
| 244 | 336 |
| 245 EXPECT_NE(active_rvh()->GetSiteInstance(), | 337 EXPECT_NE(active_rvh()->GetSiteInstance(), |
| 246 contents2->GetRenderViewHost()->GetSiteInstance()); | 338 contents2->GetRenderViewHost()->GetSiteInstance()); |
| 247 EXPECT_EQ(active_rvh()->GetSiteInstance()->GetProcess(), | 339 EXPECT_EQ(active_rvh()->GetSiteInstance()->GetProcess(), |
| 248 contents2->GetRenderViewHost()->GetSiteInstance()->GetProcess()); | 340 contents2->GetRenderViewHost()->GetSiteInstance()->GetProcess()); |
| 249 } | 341 } |
| 250 | 342 |
| 251 // Ensure that the browser ignores most IPC messages that arrive from a | 343 // Ensure that the browser ignores most IPC messages that arrive from a |
| 252 // RenderViewHost that has been swapped out. We do not want to take | 344 // RenderViewHost that has been swapped out. We do not want to take |
| 253 // action on requests from a non-active renderer. The main exception is | 345 // action on requests from a non-active renderer. The main exception is |
| 254 // for synchronous messages, which cannot be ignored without leaving the | 346 // for synchronous messages, which cannot be ignored without leaving the |
| 255 // renderer in a stuck state. See http://crbug.com/93427. | 347 // renderer in a stuck state. See http://crbug.com/93427. |
| 256 TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) { | 348 TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) { |
| 257 const GURL kChromeURL("chrome://foo"); | 349 const GURL kChromeURL("chrome://foo"); |
| 258 const GURL kDestUrl("http://www.google.com/"); | 350 const GURL kDestUrl("http://www.google.com/"); |
| 351 std::vector<FaviconURL> icons; | |
| 259 | 352 |
| 260 // Navigate our first tab to a chrome url and then to the destination. | 353 // Navigate our first tab to a chrome url and then to the destination. |
| 261 NavigateActiveAndCommit(kChromeURL); | 354 NavigateActiveAndCommit(kChromeURL); |
| 262 TestRenderViewHost* ntp_rvh = static_cast<TestRenderViewHost*>( | 355 TestRenderViewHost* ntp_rvh = static_cast<TestRenderViewHost*>( |
| 263 contents()->GetRenderManagerForTesting()->current_host()); | 356 contents()->GetRenderManagerForTesting()->current_host()); |
| 264 | 357 |
| 265 // Send an update title message and make sure it works. | 358 // Send an update favicon message and make sure it works. |
| 266 const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title"); | 359 const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title"); |
| 267 blink::WebTextDirection direction = blink::WebTextDirectionLeftToRight; | 360 { |
| 268 EXPECT_TRUE(ntp_rvh->OnMessageReceived( | 361 IpcMessageObserver observer(contents()); |
| 269 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction))); | 362 EXPECT_TRUE(ntp_rvh->OnMessageReceived( |
| 270 EXPECT_EQ(ntp_title, contents()->GetTitle()); | 363 ViewHostMsg_UpdateFaviconURL( |
| 271 | 364 rvh()->GetRoutingID(), 0, icons))); |
| 272 // Navigate to a cross-site URL. | 365 EXPECT_TRUE(observer.favicon_received()); |
| 273 contents()->GetController().LoadURL( | 366 } |
| 274 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); | |
| 275 EXPECT_TRUE(contents()->cross_navigation_pending()); | |
| 276 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>( | |
| 277 contents()->GetRenderManagerForTesting()->pending_render_view_host()); | |
| 278 ASSERT_TRUE(dest_rvh); | |
| 279 EXPECT_NE(ntp_rvh, dest_rvh); | |
| 280 | |
| 281 // Create one more view in the same SiteInstance where dest_rvh2 | 367 // Create one more view in the same SiteInstance where dest_rvh2 |
| 282 // exists so that it doesn't get deleted on navigation to another | 368 // exists so that it doesn't get deleted on navigation to another |
| 283 // site. | 369 // site. |
| 284 static_cast<SiteInstanceImpl*>(ntp_rvh->GetSiteInstance())-> | 370 static_cast<SiteInstanceImpl*>(ntp_rvh->GetSiteInstance())-> |
| 285 increment_active_view_count(); | 371 increment_active_view_count(); |
| 286 | 372 |
| 287 // BeforeUnload finishes. | |
| 288 ntp_rvh->SendBeforeUnloadACK(true); | |
| 289 | 373 |
| 290 // Assume SwapOutACK times out, so the dest_rvh proceeds and commits. | 374 // Navigate to a cross-site URL. |
| 291 dest_rvh->SendNavigate(101, kDestUrl); | 375 NavigateActiveAndCommit(kDestUrl); |
| 376 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>( | |
| 377 contents()->GetRenderViewHost()); | |
| 378 ASSERT_TRUE(dest_rvh); | |
| 379 EXPECT_NE(ntp_rvh, dest_rvh); | |
| 292 | 380 |
| 293 // The new RVH should be able to update its title. | 381 // The new RVH should be able to update its favicon. |
| 294 const base::string16 dest_title = base::ASCIIToUTF16("Google"); | 382 const base::string16 dest_title = base::ASCIIToUTF16("Google"); |
| 295 EXPECT_TRUE(dest_rvh->OnMessageReceived( | 383 { |
| 296 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 101, dest_title, | 384 IpcMessageObserver observer(contents()); |
| 297 direction))); | 385 EXPECT_TRUE( |
| 298 EXPECT_EQ(dest_title, contents()->GetTitle()); | 386 dest_rvh->OnMessageReceived( |
| 387 ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons))); | |
| 388 EXPECT_TRUE(observer.favicon_received()); | |
| 389 } | |
| 299 | 390 |
| 300 // The old renderer, being slow, now updates the title. It should be filtered | 391 // The old renderer, being slow, now updates the title. It should be filtered |
|
Charlie Reis
2014/03/21 21:35:13
s/title/favicon/
nasko
2014/03/24 17:48:11
Done.
| |
| 301 // out and not take effect. | 392 // out and not take effect. |
| 302 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, ntp_rvh->rvh_state()); | 393 EXPECT_TRUE(ntp_rvh->IsSwappedOut()); |
| 303 EXPECT_TRUE(ntp_rvh->OnMessageReceived( | 394 { |
| 304 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction))); | 395 IpcMessageObserver observer(contents()); |
| 305 EXPECT_EQ(dest_title, contents()->GetTitle()); | 396 EXPECT_TRUE( |
| 397 ntp_rvh->OnMessageReceived( | |
| 398 ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons))); | |
| 399 EXPECT_FALSE(observer.favicon_received()); | |
| 400 } | |
| 401 | |
| 402 // The same logic should apply to RenderFrameHosts as well and routing through | |
| 403 // swapped out RFH shouldn't be allowed. Use a PluginCrashObserver to check | |
| 404 // if the IPC message is allowed through or not. | |
| 405 { | |
| 406 IpcMessageObserver observer(contents()); | |
| 407 // TODO(nasko): The following line shouldn't be needed when we are properly | |
| 408 // swapping out RFH objects or move to proxy objects. | |
| 409 //ntp_rvh->main_render_frame_host()->set_swapped_out(true); | |
| 410 //EXPECT_TRUE(ntp_rvh->main_render_frame_host()->is_swapped_out()); | |
|
Charlie Reis
2014/03/21 21:35:13
Let's remove these lines until they're needed.
nasko
2014/03/24 17:48:11
Done.
| |
| 411 EXPECT_TRUE(ntp_rvh->main_render_frame_host()->OnMessageReceived( | |
| 412 FrameHostMsg_PluginCrashed( | |
| 413 main_rfh()->GetRoutingID(), base::FilePath(), 0))); | |
| 414 EXPECT_FALSE(observer.plugin_crashed()); | |
| 415 } | |
| 306 | 416 |
| 307 // We cannot filter out synchronous IPC messages, because the renderer would | 417 // We cannot filter out synchronous IPC messages, because the renderer would |
| 308 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example | 418 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example |
| 309 // that can run easily within a unit test, and that needs to receive a reply | 419 // that can run easily within a unit test, and that needs to receive a reply |
| 310 // without showing an actual dialog. | 420 // without showing an actual dialog. |
| 311 MockRenderProcessHost* ntp_process_host = | 421 MockRenderProcessHost* ntp_process_host = |
| 312 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess()); | 422 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess()); |
| 313 ntp_process_host->sink().ClearMessages(); | 423 ntp_process_host->sink().ClearMessages(); |
| 314 const base::string16 msg = base::ASCIIToUTF16("Message"); | 424 const base::string16 msg = base::ASCIIToUTF16("Message"); |
| 315 bool result = false; | 425 bool result = false; |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1022 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())-> | 1132 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())-> |
| 1023 increment_active_view_count(); | 1133 increment_active_view_count(); |
| 1024 | 1134 |
| 1025 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't | 1135 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't |
| 1026 // happen, but we have seen it when going back quickly across many entries | 1136 // happen, but we have seen it when going back quickly across many entries |
| 1027 // (http://crbug.com/93427). | 1137 // (http://crbug.com/93427). |
| 1028 contents()->GetController().GoBack(); | 1138 contents()->GetController().GoBack(); |
| 1029 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack()); | 1139 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack()); |
| 1030 contents()->ProceedWithCrossSiteNavigation(); | 1140 contents()->ProceedWithCrossSiteNavigation(); |
| 1031 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack()); | 1141 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack()); |
| 1032 rvh2->SwapOut(); | 1142 StartCrossSiteTransition(contents()); |
| 1033 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK()); | 1143 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK()); |
| 1034 | 1144 |
| 1035 // The back navigation commits. | 1145 // The back navigation commits. |
| 1036 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); | 1146 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); |
| 1037 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); | 1147 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); |
| 1038 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state()); | 1148 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state()); |
| 1039 | 1149 |
| 1040 // We should be able to navigate forward. | 1150 // We should be able to navigate forward. |
| 1041 contents()->GetController().GoForward(); | 1151 contents()->GetController().GoForward(); |
| 1042 contents()->ProceedWithCrossSiteNavigation(); | 1152 contents()->ProceedWithCrossSiteNavigation(); |
| 1153 StartCrossSiteTransition(contents()); | |
| 1043 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); | 1154 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); |
| 1044 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); | 1155 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); |
| 1045 EXPECT_EQ(rvh2, rvh()); | 1156 EXPECT_EQ(rvh2, rvh()); |
| 1046 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); | 1157 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); |
| 1047 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state()); | 1158 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state()); |
| 1048 rvh1->OnSwappedOut(false); | 1159 rvh1->OnSwappedOut(false); |
| 1049 EXPECT_TRUE(rvh1->IsSwappedOut()); | 1160 EXPECT_TRUE(rvh1->IsSwappedOut()); |
| 1050 } | 1161 } |
| 1051 | 1162 |
| 1052 // Test that we create swapped out RVHs for the opener chain when navigating an | 1163 // Test that we create swapped out RVHs for the opener chain when navigating an |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1573 | 1684 |
| 1574 // Simulate the swap out ack. | 1685 // Simulate the swap out ack. |
| 1575 rvh1->OnSwappedOut(false); | 1686 rvh1->OnSwappedOut(false); |
| 1576 | 1687 |
| 1577 // rvh1 should be swapped out. | 1688 // rvh1 should be swapped out. |
| 1578 EXPECT_FALSE(destruction_observer.rvh_deleted()); | 1689 EXPECT_FALSE(destruction_observer.rvh_deleted()); |
| 1579 EXPECT_TRUE(rvh1->IsSwappedOut()); | 1690 EXPECT_TRUE(rvh1->IsSwappedOut()); |
| 1580 } | 1691 } |
| 1581 | 1692 |
| 1582 } // namespace content | 1693 } // namespace content |
| OLD | NEW |