11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/command_line.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_path.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/time/time.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/frame_host/cross_site_transferring_request.h"
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/browser/frame_host/navigation_before_commit_info.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_controller_impl.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/frame_host/navigation_request.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/frame_host/navigator.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/browser/frame_host/navigator_impl.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/frame_host/render_frame_host_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/site_instance_impl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/web_ui_controller_factory_registry.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/notification_service.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/render_process_host.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/render_widget_host_iterator.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_controller.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/common/content_switches.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/javascript_message_type.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/url_utils.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_render_process_host.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_notification_tracker.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/test_content_browser_client.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/test_content_client.h"
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/test/test_render_frame_host.h"
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/test/test_render_view_host.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/test_web_contents.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class RenderFrameHostManagerTestWebUIControllerFactory
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public WebUIControllerFactory {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManagerTestWebUIControllerFactory()
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : should_create_webui_(false) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~RenderFrameHostManagerTestWebUIControllerFactory() {}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_should_create_webui(bool should_create_webui) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should_create_webui_ = should_create_webui;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIFactory implementation.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebUIController* CreateWebUIControllerForURL(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebUI* web_ui, const GURL& url) const OVERRIDE {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!(should_create_webui_ && HasWebUIScheme(url)))
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new WebUIController(web_ui);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url) const OVERRIDE {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebUI::kNoWebUI;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool UseWebUIForURL(BrowserContext* browser_context,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const GURL& url) const OVERRIDE {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return HasWebUIScheme(url);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const GURL& url) const OVERRIDE {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return HasWebUIScheme(url);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_create_webui_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManagerTestWebUIControllerFactory);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class BeforeUnloadFiredWebContentsDelegate : public WebContentsDelegate {
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BeforeUnloadFiredWebContentsDelegate() {}
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~BeforeUnloadFiredWebContentsDelegate() {}
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void BeforeUnloadFired(WebContents* web_contents,
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 bool proceed,
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 bool* proceed_to_fire_unload) OVERRIDE {
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *proceed_to_fire_unload = proceed;
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BeforeUnloadFiredWebContentsDelegate);
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This observer keeps track of the last deleted RenderViewHost to avoid
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// accessing it and causing use-after-free condition.
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass RenderViewHostDeletedObserver : public WebContentsObserver {
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RenderViewHostDeletedObserver(RenderViewHost* rvh)
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      : WebContentsObserver(WebContents::FromRenderViewHost(rvh)),
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        process_id_(rvh->GetProcess()->GetID()),
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        routing_id_(rvh->GetRoutingID()),
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        deleted_(false) {
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE {
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (render_view_host->GetProcess()->GetID() == process_id_ &&
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        render_view_host->GetRoutingID() == routing_id_) {
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      deleted_ = true;
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool deleted() {
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return deleted_;
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int process_id_;
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int routing_id_;
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool deleted_;
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DISALLOW_COPY_AND_ASSIGN(RenderViewHostDeletedObserver);
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This observer keeps track of the last deleted RenderFrameHost to avoid
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// accessing it and causing use-after-free condition.
135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass RenderFrameHostDeletedObserver : public WebContentsObserver {
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  RenderFrameHostDeletedObserver(RenderFrameHost* rfh)
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)),
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        process_id_(rfh->GetProcess()->GetID()),
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        routing_id_(rfh->GetRoutingID()),
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        deleted_(false) {
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE {
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (render_frame_host->GetProcess()->GetID() == process_id_ &&
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        render_frame_host->GetRoutingID() == routing_id_) {
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      deleted_ = true;
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool deleted() {
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return deleted_;
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int process_id_;
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int routing_id_;
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool deleted_;
159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(RenderFrameHostDeletedObserver);
161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This observer is used to check whether IPC messages are being filtered for
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// swapped out RenderFrameHost objects. It observes the plugin crash and favicon
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// update events, which the FilterMessagesWhileSwappedOut test simulates being
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// sent. The test is successful if the event is not observed.
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// See http://crbug.com/351815
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass PluginFaviconMessageObserver : public WebContentsObserver {
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PluginFaviconMessageObserver(WebContents* web_contents)
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      : WebContentsObserver(web_contents),
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        plugin_crashed_(false),
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        favicon_received_(false) { }
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void PluginCrashed(const base::FilePath& plugin_path,
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             base::ProcessId plugin_pid) OVERRIDE {
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    plugin_crashed_ = true;
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void DidUpdateFaviconURL(
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      const std::vector<FaviconURL>& candidates) OVERRIDE {
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    favicon_received_ = true;
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool plugin_crashed() {
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return plugin_crashed_;
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool favicon_received() {
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return favicon_received_;
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool plugin_crashed_;
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool favicon_received_;
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DISALLOW_COPY_AND_ASSIGN(PluginFaviconMessageObserver);
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Ensures that RenderFrameDeleted and RenderFrameCreated are called in a
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// consistent manner.
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class FrameLifetimeConsistencyChecker : public WebContentsObserver {
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  explicit FrameLifetimeConsistencyChecker(WebContentsImpl* web_contents)
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : WebContentsObserver(web_contents) {
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RenderViewCreated(web_contents->GetRenderViewHost());
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RenderFrameCreated(web_contents->GetMainFrame());
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE {
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::pair<int, int> routing_pair =
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        std::make_pair(render_frame_host->GetProcess()->GetID(),
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       render_frame_host->GetRoutingID());
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool was_live_already = !live_routes_.insert(routing_pair).second;
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool was_used_before = deleted_routes_.count(routing_pair) != 0;
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (was_live_already) {
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FAIL() << "RenderFrameCreated called more than once for routing pair: "
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << Format(render_frame_host);
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else if (was_used_before) {
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FAIL() << "RenderFrameCreated called for routing pair "
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << Format(render_frame_host) << " that was previously deleted.";
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE {
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::pair<int, int> routing_pair =
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        std::make_pair(render_frame_host->GetProcess()->GetID(),
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       render_frame_host->GetRoutingID());
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool was_live = live_routes_.erase(routing_pair);
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool was_dead_already = !deleted_routes_.insert(routing_pair).second;
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (was_dead_already) {
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FAIL() << "RenderFrameDeleted called more than once for routing pair "
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << Format(render_frame_host);
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else if (!was_live) {
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FAIL() << "RenderFrameDeleted called for routing pair "
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << Format(render_frame_host)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << " for which RenderFrameCreated was never called";
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string Format(RenderFrameHost* render_frame_host) {
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return base::StringPrintf(
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "(%d, %d -> %s )",
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        render_frame_host->GetProcess()->GetID(),
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        render_frame_host->GetRoutingID(),
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        render_frame_host->GetSiteInstance()->GetSiteURL().spec().c_str());
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::set<std::pair<int, int> > live_routes_;
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::set<std::pair<int, int> > deleted_routes_;
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class RenderFrameHostManagerTest
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public RenderViewHostImplTestHarness {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostImplTestHarness::SetUp();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebUIControllerFactory::RegisterFactory(&factory_);
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    lifetime_checker_.reset(new FrameLifetimeConsistencyChecker(contents()));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    lifetime_checker_.reset();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostImplTestHarness::TearDown();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_should_create_webui(bool should_create_webui) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    factory_.set_should_create_webui(should_create_webui);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NavigateActiveAndCommit(const GURL& url) {
27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Note: we navigate the active RenderFrameHost because previous navigations
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // won't have committed yet, so NavigateAndCommit does the wrong thing
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for us.
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    controller().LoadURL(
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRenderViewHost* old_rvh = test_rvh();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Simulate the BeforeUnload_ACK that is received from the current renderer
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for a cross-site navigation.
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (old_rvh != active_rvh()) {
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      old_rvh->SendBeforeUnloadACK(true);
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, old_rvh->rvh_state());
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Commit the navigation with a new page ID.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 max_page_id = contents()->GetMaxPageIDForSiteInstance(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        active_rvh()->GetSiteInstance());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Use an observer to avoid accessing a deleted renderer later on when the
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // state is being checked.
298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    RenderViewHostDeletedObserver rvh_observer(old_rvh);
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    active_test_rvh()->SendNavigate(max_page_id + 1, url);
300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Make sure that we start to run the unload handler at the time of commit.
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool expecting_rvh_shutdown = false;
30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (old_rvh != active_rvh() && !rvh_observer.deleted()) {
30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (!static_cast<SiteInstanceImpl*>(
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              old_rvh->GetSiteInstance())->active_view_count()) {
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        expecting_rvh_shutdown = true;
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN,
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  old_rvh->rvh_state());
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      } else {
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  old_rvh->rvh_state());
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      }
31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Simulate the swap out ACK coming from the pending renderer.  This should
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // either shut down the old RVH or leave it in a swapped out state.
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (old_rvh != active_rvh()) {
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      old_rvh->OnSwappedOut(false);
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (expecting_rvh_shutdown) {
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_TRUE(rvh_observer.deleted());
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      } else {
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT,
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  old_rvh->rvh_state());
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      }
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ShouldSwapProcesses(RenderFrameHostManager* manager,
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           const NavigationEntryImpl* current_entry,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const NavigationEntryImpl* new_entry) const {
3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CHECK(new_entry);
3326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BrowserContext* browser_context =
3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        manager->delegate_->GetControllerForRenderManager().GetBrowserContext();
3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const GURL& current_effective_url = current_entry ?
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        SiteInstanceImpl::GetEffectiveURL(browser_context,
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                          current_entry->GetURL()) :
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        manager->render_frame_host_->GetSiteInstance()->GetSiteURL();
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    bool current_is_view_source_mode = current_entry ?
3396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        current_entry->IsViewSourceMode() : new_entry->IsViewSourceMode();
3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return manager->ShouldSwapBrowsingInstancesForNavigation(
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        current_effective_url,
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        current_is_view_source_mode,
3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new_entry->site_instance(),
3446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        SiteInstanceImpl::GetEffectiveURL(browser_context, new_entry->GetURL()),
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new_entry->IsViewSourceMode());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Creates a test RenderViewHost that's swapped out.
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestRenderViewHost* CreateSwappedOutRenderViewHost() {
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL kChromeURL("chrome://foo");
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL kDestUrl("http://www.google.com/");
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Navigate our first tab to a chrome url and then to the destination.
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NavigateActiveAndCommit(kChromeURL);
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Navigate to a cross-site URL.
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    contents()->GetController().LoadURL(
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(contents()->cross_navigation_pending());
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Manually increase the number of active views in the
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // SiteInstance that ntp_rfh belongs to, to prevent it from being
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // destroyed when it gets swapped out.
3656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    static_cast<SiteInstanceImpl*>(ntp_rfh->GetSiteInstance())->
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        increment_active_view_count();
3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestRenderFrameHost* dest_rfh = contents()->GetPendingMainFrame();
3696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CHECK(dest_rfh);
3706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_NE(ntp_rfh, dest_rfh);
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // BeforeUnload finishes.
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ntp_rfh->GetRenderViewHost()->SendBeforeUnloadACK(true);
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    dest_rfh->SendNavigate(101, kDestUrl);
3766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ntp_rfh->OnSwappedOut(false);
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->IsSwappedOut());
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return ntp_rfh->GetRenderViewHost();
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationRequest* GetNavigationRequestForRenderFrameManager(
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RenderFrameHostManager* manager) const {
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return manager->navigation_request_for_testing();
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void EnableBrowserSideNavigation() {
38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        switches::kEnableBrowserSideNavigation);
39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManagerTestWebUIControllerFactory factory_;
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<FrameLifetimeConsistencyChecker> lifetime_checker_;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that when you navigate from a chrome:// url to another page, and
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then do that same thing in another tab, that the two resulting pages have
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a regression test for bug 9364.
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_should_create_webui(true);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kChromeUrl("chrome://foo");
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDestUrl("http://www.google.com/");
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate our first tab to the chrome url and then to the destination,
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ensuring we grant bindings to the chrome URL.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateActiveAndCommit(kChromeUrl);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(active_rvh()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateActiveAndCommit(kDestUrl);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(contents()->GetPendingMainFrame());
4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a second tab.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> contents2(
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), NULL));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the two URLs in the second tab. Note that the first navigation creates
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // a RFH that's not pending (since there is no cross-site transition), so
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we use the committed one.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* ntp_rfh2 = contents2->GetMainFrame();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents2->cross_navigation_pending());
4246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ntp_rfh2->SendNavigate(100, kChromeUrl);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second one is the opposite, creating a cross-site transition and
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a beforeunload ack.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents2->cross_navigation_pending());
4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* dest_rfh2 = contents2->GetPendingMainFrame();
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(dest_rfh2);
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ntp_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true);
4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  dest_rfh2->SendNavigate(101, kDestUrl);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The two RFH's should be different in every way.
4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(contents()->GetMainFrame()->GetProcess(), dest_rfh2->GetProcess());
4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(),
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            dest_rfh2->GetSiteInstance());
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(dest_rfh2->GetSiteInstance()->IsRelatedSiteInstance(
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   contents()->GetMainFrame()->GetSiteInstance()));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate both to the new tab page, and verify that they share a
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RenderProcessHost (not a SiteInstance).
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateActiveAndCommit(kChromeUrl);
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(contents()->GetPendingMainFrame());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
4516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  dest_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true);
4526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents2->GetPendingMainFrame()->SendNavigate(102, kChromeUrl);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(),
4556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            contents2->GetMainFrame()->GetSiteInstance());
4566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(contents()->GetMainFrame()->GetSiteInstance()->GetProcess(),
4576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            contents2->GetMainFrame()->GetSiteInstance()->GetProcess());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that the browser ignores most IPC messages that arrive from a
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewHost that has been swapped out.  We do not want to take
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// action on requests from a non-active renderer.  The main exception is
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for synchronous messages, which cannot be ignored without leaving the
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renderer in a stuck state.  See http://crbug.com/93427.
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kChromeURL("chrome://foo");
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDestUrl("http://www.google.com/");
468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<FaviconURL> icons;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate our first tab to a chrome url and then to the destination.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateActiveAndCommit(kChromeURL);
4726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Send an update favicon message and make sure it works.
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title");
476effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
477effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PluginFaviconMessageObserver observer(contents());
4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->OnMessageReceived(
479effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    ViewHostMsg_UpdateFaviconURL(
4806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        ntp_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(observer.favicon_received());
482effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
4836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Create one more view in the same SiteInstance where ntp_rfh
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // exists so that it doesn't get deleted on navigation to another
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // site.
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static_cast<SiteInstanceImpl*>(ntp_rfh->GetSiteInstance())->
4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
490effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Navigate to a cross-site URL.
491effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NavigateActiveAndCommit(kDestUrl);
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* dest_rfh = contents()->GetMainFrame();
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(dest_rfh);
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(ntp_rfh, dest_rfh);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The new RVH should be able to update its favicon.
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 dest_title = base::ASCIIToUTF16("Google");
498effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
499effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PluginFaviconMessageObserver observer(contents());
500effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(
5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        dest_rfh->GetRenderViewHost()->OnMessageReceived(
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            ViewHostMsg_UpdateFaviconURL(
5036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(observer.favicon_received());
505effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
506effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The old renderer, being slow, now updates the favicon. It should be
508effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // filtered out and not take effect.
5096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->IsSwappedOut());
510effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
511effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PluginFaviconMessageObserver observer(contents());
512effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(
5136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ntp_rfh->GetRenderViewHost()->OnMessageReceived(
5146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            ViewHostMsg_UpdateFaviconURL(
5156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
516effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(observer.favicon_received());
517effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
518effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
519effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The same logic should apply to RenderFrameHosts as well and routing through
520effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // swapped out RFH shouldn't be allowed. Use a PluginCrashObserver to check
521effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // if the IPC message is allowed through or not.
522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
523effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PluginFaviconMessageObserver observer(contents());
5246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(ntp_rfh->OnMessageReceived(
525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    FrameHostMsg_PluginCrashed(
5266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        ntp_rfh->GetRoutingID(), base::FilePath(), 0)));
527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(observer.plugin_crashed());
528effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot filter out synchronous IPC messages, because the renderer would
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be left waiting for a reply.  We pick RunBeforeUnloadConfirm as an example
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that can run easily within a unit test, and that needs to receive a reply
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without showing an actual dialog.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRenderProcessHost* ntp_process_host =
5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      static_cast<MockRenderProcessHost*>(ntp_rfh->GetProcess());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ntp_process_host->sink().ClearMessages();
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 msg = base::ASCIIToUTF16("Message");
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 unused;
540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FrameHostMsg_RunBeforeUnloadConfirm before_unload_msg(
541c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      ntp_rfh->GetRoutingID(), kChromeURL, msg, false, &result, &unused);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable pumping for check in BrowserMessageFilter::CheckCanDispatchOnUI.
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  before_unload_msg.EnableMessagePumping();
544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(ntp_rfh->OnMessageReceived(before_unload_msg));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ntp_process_host->sink().GetUniqueMessageMatching(IPC_REPLY_ID));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also test RunJavaScriptMessage.
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ntp_process_host->sink().ClearMessages();
549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FrameHostMsg_RunJavaScriptMessage js_msg(
550c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      ntp_rfh->GetRoutingID(), msg, msg, kChromeURL,
551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      JAVASCRIPT_MESSAGE_TYPE_CONFIRM, &result, &unused);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_msg.EnableMessagePumping();
553c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(ntp_rfh->OnMessageReceived(js_msg));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ntp_process_host->sink().GetUniqueMessageMatching(IPC_REPLY_ID));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, WhiteListSwapCompositorFrame) {
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost();
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestRenderWidgetHostView* swapped_out_rwhv =
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<TestRenderWidgetHostView*>(swapped_out_rvh->GetView());
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(swapped_out_rwhv->did_swap_compositor_frame());
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRenderProcessHost* process_host =
564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<MockRenderProcessHost*>(swapped_out_rvh->GetProcess());
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  process_host->sink().ClearMessages();
566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  cc::CompositorFrame frame;
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ViewHostMsg_SwapCompositorFrame msg(
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      rvh()->GetRoutingID(), 0, frame, std::vector<IPC::Message>());
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(swapped_out_rvh->OnMessageReceived(msg));
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(swapped_out_rwhv->did_swap_compositor_frame());
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Test if RenderViewHost::GetRenderWidgetHosts() only returns active
5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// widgets.
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, GetRenderWidgetHostsReturnsActiveViews) {
5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost();
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(swapped_out_rvh->IsSwappedOut());
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<RenderWidgetHostIterator> widgets(
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RenderWidgetHost::GetRenderWidgetHosts());
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // We know that there is the only one active widget. Another view is
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // now swapped out, so the swapped out view is not included in the
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // list.
58658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RenderWidgetHost* widget = widgets->GetNextHost();
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(widgets->GetNextHost());
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RenderViewHost* rvh = RenderViewHost::From(widget);
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            static_cast<RenderViewHostImpl*>(rvh)->rvh_state());
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Test if RenderViewHost::GetRenderWidgetHosts() returns a subset of
5947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RenderViewHostImpl::GetAllRenderWidgetHosts().
5957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RenderViewHost::GetRenderWidgetHosts() returns only active widgets, but
5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RenderViewHostImpl::GetAllRenderWidgetHosts() returns everything
5977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// including swapped out ones.
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest,
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       GetRenderWidgetHostsWithinGetAllRenderWidgetHosts) {
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost();
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(swapped_out_rvh->IsSwappedOut());
6027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<RenderWidgetHostIterator> widgets(
60458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RenderWidgetHost::GetRenderWidgetHosts());
6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  while (RenderWidgetHost* w = widgets->GetNextHost()) {
6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool found = false;
60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<RenderWidgetHostIterator> all_widgets(
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        RenderWidgetHostImpl::GetAllRenderWidgetHosts());
61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    while (RenderWidgetHost* widget = all_widgets->GetNextHost()) {
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (w == widget) {
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        found = true;
6137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
6147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
6157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
6167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_TRUE(found);
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Test if SiteInstanceImpl::active_view_count() is correctly updated
6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// as views in a SiteInstance get swapped out and in.
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, ActiveViewCountWhileSwappingInandOut) {
6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kUrl1("http://www.google.com/");
6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kUrl2("http://www.chromium.org/");
6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate to an initial URL.
6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->NavigateAndCommit(kUrl1);
6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestRenderViewHost* rvh1 = test_rvh();
6297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SiteInstanceImpl* instance1 =
6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      static_cast<SiteInstanceImpl*>(rvh1->GetSiteInstance());
6327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(instance1->active_view_count(), 1U);
6337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Create 2 new tabs and simulate them being the opener chain for the main
6357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // tab.  They should be in the same SiteInstance.
6367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<TestWebContents> opener1(
6377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      TestWebContents::Create(browser_context(), instance1));
6387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->SetOpener(opener1.get());
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<TestWebContents> opener2(
6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      TestWebContents::Create(browser_context(), instance1));
6427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  opener1->SetOpener(opener2.get());
6437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(instance1->active_view_count(), 3U);
6457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate to a cross-site URL (different SiteInstance but same
6477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // BrowsingInstance).
6487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->NavigateAndCommit(kUrl2);
6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestRenderViewHost* rvh2 = test_rvh();
6507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SiteInstanceImpl* instance2 =
6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance());
6527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // rvh2 is on chromium.org which is different from google.com on
6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // which other tabs are.
6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(instance2->active_view_count(), 1U);
6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // There are two active views on google.com now.
6587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(instance1->active_view_count(), 2U);
6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate to the original origin (google.com).
6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->NavigateAndCommit(kUrl1);
6627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(instance1->active_view_count(), 3U);
6647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This deletes a WebContents when the given RVH is deleted. This is
6677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// only for testing whether deleting an RVH does not cause any UaF in
6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// other parts of the system. For now, this class is only used for the
6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// next test cases to detect the bug mentioned at
6707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// http://crbug.com/259859.
6711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class RenderViewHostDestroyer : public WebContentsObserver {
6727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
6737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RenderViewHostDestroyer(RenderViewHost* render_view_host,
6747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          WebContents* web_contents)
6751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)),
6761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        render_view_host_(render_view_host),
6777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        web_contents_(web_contents) {}
6787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void RenderViewDeleted(
6801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      RenderViewHost* render_view_host) OVERRIDE {
6811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (render_view_host == render_view_host_)
6821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      delete web_contents_;
6837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
6861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RenderViewHost* render_view_host_;
6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebContents* web_contents_;
6881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestroyer);
6907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Test if ShutdownRenderViewHostsInSiteInstance() does not touch any
6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RenderWidget that has been freed while deleting a RenderViewHost in
6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// a previous iteration. This is a regression test for
6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// http://crbug.com/259859.
696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest,
6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       DetectUseAfterFreeInShutdownRenderViewHostsInSiteInstance) {
6987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kChromeURL("chrome://newtab");
6997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kUrl1("http://www.google.com");
7007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kUrl2("http://www.chromium.org");
7017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate our first tab to a chrome url and then to the destination.
7037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  NavigateActiveAndCommit(kChromeURL);
7046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
7057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Create one more tab and navigate to kUrl1.  web_contents is not
7077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // wrapped as scoped_ptr since it intentionally deleted by destroyer
7087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // below as part of this test.
7097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestWebContents* web_contents =
7106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      TestWebContents::Create(browser_context(), ntp_rfh->GetSiteInstance());
7117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  web_contents->NavigateAndCommit(kUrl1);
7126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RenderViewHostDestroyer destroyer(ntp_rfh->GetRenderViewHost(),
7136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    web_contents);
7147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // This causes the first tab to navigate to kUrl2, which destroys
7166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // the ntp_rfh in ShutdownRenderViewHostsInSiteInstance(). When
7176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ntp_rfh is destroyed, it also destroys the RVHs in web_contents
7187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // too. This can test whether
7197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // SiteInstanceImpl::ShutdownRenderViewHostsInSiteInstance() can
7207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // touch any object freed in this way or not while iterating through
7217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // all widgets.
7227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->NavigateAndCommit(kUrl2);
7237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When there is an error with the specified page, renderer exits view-source
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mode. See WebFrameImpl::DidFail(). We check by this test that
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EnableViewSourceMode message is sent on every navigation regardless
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderView is being newly created or reused.
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, AlwaysSendEnableViewSourceMode) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kChromeUrl("chrome://foo");
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl("view-source:http://foo");
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to navigate to some page at first since without this, the first
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation will reuse the SiteInstance created by Init(), and the second
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one will create a new SiteInstance. Because current_instance and
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new_instance will be different, a new RenderViewHost will be created for
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the second navigation. We have to avoid this in order to exercise the
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // target code patch.
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateActiveAndCommit(kChromeUrl);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate response from RenderFrame for DispatchBeforeUnload.
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
7466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetMainFrame()->OnMessageReceived(FrameHostMsg_BeforeUnload_ACK(
7476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      contents()->GetMainFrame()->GetRoutingID(), true, now, now));
7486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(contents()->GetPendingMainFrame())
7496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      << "Expected new pending RenderFrameHost to be created.";
7506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RenderFrameHost* last_rfh = contents()->GetPendingMainFrame();
7516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int32 new_id =
7526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      contents()->GetMaxPageIDForSiteInstance(last_rfh->GetSiteInstance()) + 1;
7536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetPendingMainFrame()->SendNavigate(new_id, kUrl);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(controller().GetLastCommittedEntry());
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(kUrl == controller().GetLastCommittedEntry()->GetURL());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller().GetPendingEntry());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because we're using TestWebContents and TestRenderViewHost in this
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unittest, no one calls WebContentsImpl::RenderViewCreated(). So, we see no
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // EnableViewSourceMode message, here.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear queued messages before load.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate, again.
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The same RenderViewHost should be reused.
7686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(contents()->GetPendingMainFrame());
7696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(last_rfh == contents()->GetMainFrame());
7706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Navigate using the returned page_id.
7716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetMainFrame()->SendNavigate(new_id, kUrl);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller().GetPendingEntry());
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // New message should be sent out to make sure to enter view-source mode.
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process()->sink().GetUniqueMessageMatching(
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ViewMsg_EnableViewSourceMode::ID));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the Init function by checking the initial RenderViewHost.
780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, Init) {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Using TestBrowserContext.
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstanceImpl* instance =
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<SiteInstanceImpl*>(SiteInstance::Create(browser_context()));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(instance->HasSite());
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> web_contents(
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), instance));
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderViewHostImpl* rvh = manager->current_host();
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* rfh = manager->current_frame_host();
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(rvh);
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(rfh);
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(rvh, rfh->render_view_host());
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(instance, rvh->GetSiteInstance());
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(web_contents.get(), rvh->GetDelegate());
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(web_contents.get(), rfh->delegate());
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager->GetRenderWidgetHostView());
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_render_view_host());
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the Navigate function. We navigate three sites consecutively and check
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// how the pending/committed RenderViewHost are modified.
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, Navigate) {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance = SiteInstance::Create(browser_context());
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> web_contents(
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), instance));
8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notifications.ListenFor(NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          Source<WebContents>(web_contents.get()));
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1) The first navigation. --------------------------
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry1(
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(),
8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false /* is_renderer_init */);
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host = manager->Navigate(entry1);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The RenderFrameHost created in Init will be reused.
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
830effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit to SiteInstance should be delayed until RenderView commit.
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(host);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSite());
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->SetSite(kUrl1);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2) Navigate to next site. -------------------------
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.google.com/foo");
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry2(
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl2,
842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Referrer(kUrl1, blink::WebReferrerPolicyDefault),
8431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_LINK,
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true /* is_renderer_init */);
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host = manager->Navigate(entry2);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The RenderFrameHost created in Init will be reused.
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
852effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(host);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSite());
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3) Cross-site navigate to next site. --------------
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl3("http://webkit.org/");
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry3(
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl3,
862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Referrer(kUrl2, blink::WebReferrerPolicyDefault),
8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_LINK,
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false /* is_renderer_init */);
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host = manager->Navigate(entry3);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new RenderFrameHost should be created.
8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager->pending_frame_host());
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(host, manager->pending_frame_host());
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications.Reset();
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
874effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(manager->pending_frame_host());
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(host);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSite());
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the pending RenderFrameHost has been committed.
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should observe a notification.
8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(
8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED));
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests WebUI creation.
888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, WebUI) {
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_should_create_webui(true);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance = SiteInstance::Create(browser_context());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> web_contents(
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), instance));
894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->current_host()->IsRenderViewLive());
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl("chrome://foo");
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            Referrer(), base::string16() /* title */,
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            ui::PAGE_TRANSITION_TYPED,
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            false /* is_renderer_init */);
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host = manager->Navigate(entry);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We commit the pending RenderFrameHost immediately because the previous
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // RenderFrameHost was not live.  We test a case where it is live in
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebUIInNewTab.
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(host);
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's important that the site instance get set on the Web UI page as soon
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as the navigation starts, rather than lazily after it commits, so we don't
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // try to re-use the SiteInstance/process for non Web UI things that may
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get loaded in between.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSite());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl, host->GetSiteInstance()->GetSiteURL());
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Web UI is committed immediately because the RenderViewHost has not been
9215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // used yet. UpdateStateForNavigate() took the short cut path.
9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_web_ui());
9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager->web_ui());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
926effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      host->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that we can open a WebUI link in a new tab from a WebUI page and still
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// grant the correct bindings.  http://crbug.com/189101.
933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_should_create_webui(true);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SiteInstance* blank_instance = SiteInstance::Create(browser_context());
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a blank tab.
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestWebContents> web_contents1(
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestWebContents::Create(browser_context(), blank_instance));
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager1 =
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      web_contents1->GetRenderManagerForTesting();
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test the case that new RVH is considered live.
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  manager1->current_host()->CreateRenderView(
944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::string16(), -1, MSG_ROUTING_NONE, -1, false);
9451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manager1->current_host()->IsRenderViewLive());
9461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manager1->current_frame_host()->IsRenderFrameLive());
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a WebUI page.
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kUrl1("chrome://foo");
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             Referrer(), base::string16() /* title */,
9521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             ui::PAGE_TRANSITION_TYPED,
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             false /* is_renderer_init */);
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host1 = manager1->Navigate(entry1);
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have a pending navigation to the WebUI RenderViewHost.
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It should already have bindings.
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host1, manager1->pending_frame_host());
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(host1, manager1->current_frame_host());
9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Commit and ensure we still have bindings.
964effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager1->DidNavigateFrame(host1);
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SiteInstance* webui_instance = host1->GetSiteInstance();
9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host1, manager1->current_frame_host());
9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now simulate clicking a link that opens in a new tab.
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestWebContents> web_contents2(
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestWebContents::Create(browser_context(), webui_instance));
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager2 =
974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      web_contents2->GetRenderManagerForTesting();
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure the new RVH is considered live.  This is usually done in
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // RenderWidgetHost::Init when opening a new tab from a link.
977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  manager2->current_host()->CreateRenderView(
978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::string16(), -1, MSG_ROUTING_NONE, -1, false);
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kUrl2("chrome://foo/bar");
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2,
982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             Referrer(), base::string16() /* title */,
9831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             ui::PAGE_TRANSITION_LINK,
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true /* is_renderer_init */);
9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host2 = manager2->Navigate(entry2);
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No cross-process transition happens because we are already in the right
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SiteInstance.  We should grant bindings immediately.
9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host2, manager2->current_frame_host());
9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
993effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager2->DidNavigateFrame(host2);
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we don't end up in an inconsistent state if a page does a back and
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then reload. http://crbug.com/51680
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.evil-site.com/");
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a safe site, then an evil site.
10036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This will switch RenderFrameHosts.  We cannot assert that the first and
10046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // second RFHs are different, though, because the first one may be promptly
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted.
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
10086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* evil_rfh = contents()->GetMainFrame();
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's simulate the evil page calling history.back().
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(-1);
10126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // We should have a new pending RFH.
10136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Note that in this case, the navigation has not committed, so evil_rfh will
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not be deleted yet.
10156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(evil_rfh, contents()->GetPendingMainFrame());
10166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(evil_rfh->GetRenderViewHost(),
10176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            contents()->GetPendingMainFrame()->GetRenderViewHost());
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Before that RFH has committed, the evil page reloads itself.
10205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = kUrl2;
10231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.was_within_same_page = false;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
102890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(kUrl2);
10295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetFrameTree()->root()->navigator()->DidNavigate(evil_rfh,
10316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                               params);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // That should have cancelled the pending RFH, and the evil RFH should be the
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current one.
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_render_view_host() == NULL);
10376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->pending_frame_host() ==
10386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              NULL);
10396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(evil_rfh,
10406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            contents()->GetRenderManagerForTesting()->current_frame_host());
10416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(evil_rfh->GetRenderViewHost(),
10426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            contents()->GetRenderManagerForTesting()->current_host());
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also we should not have a pending navigation entry.
10454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(contents()->GetController().GetPendingEntry() == NULL);
10464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigationEntry* entry = contents()->GetController().GetVisibleEntry();
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl2, entry->GetURL());
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that we can go back and forward even if a SwapOut ACK isn't received.
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/93427.
1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, NavigateAfterMissingSwapOutACK) {
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to two pages.
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh1 = test_rvh();
10607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep active_view_count nonzero so that no swapped out views in
10627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // this SiteInstance get forcefully deleted.
10637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(rvh1->GetSiteInstance())->
10647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
10657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh2 = test_rvh();
10687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())->
10697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go back, but suppose the SwapOut_ACK isn't received.  This shouldn't
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happen, but we have seen it when going back quickly across many entries
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (http://crbug.com/93427).
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->GetController().GoBack();
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack());
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack());
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The back navigation commits.
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
108203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(rvh2->IsWaitingForUnloadACK());
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be able to navigate forward.
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->GetController().GoForward();
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry();
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL());
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(rvh2, rvh());
10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
10925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
10935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rvh1->OnSwappedOut(false);
10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(rvh1->IsSwappedOut());
109503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, rvh1->rvh_state());
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we create swapped out RVHs for the opener chain when navigating an
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opened tab cross-process.  This allows us to support certain cross-process
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JavaScript calls (http://crbug.com/99202).
1101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, CreateSwappedOutOpenerRVHs) {
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kChromeUrl("chrome://foo");
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to an initial URL.
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
1108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh1 = test_rvh();
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 2 new tabs and simulate them being the opener chain for the main
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab.  They should be in the same SiteInstance.
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), rvh1->GetSiteInstance()));
1115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManager* opener1_manager =
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener1->GetRenderManagerForTesting();
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetOpener(opener1.get());
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> opener2(
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), rvh1->GetSiteInstance()));
1121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManager* opener2_manager =
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener2->GetRenderManagerForTesting();
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  opener1->SetOpener(opener2.get());
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a cross-site URL (different SiteInstance but same
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BrowsingInstance).
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh2 = test_rvh();
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(rvh1->GetSiteInstance(), rvh2->GetSiteInstance());
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(rvh1->GetSiteInstance()->IsRelatedSiteInstance(
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  rvh2->GetSiteInstance()));
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure rvh1 is placed on swapped out list of the current tab.
11345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager->IsRVHOnSwappedOutList(rvh1));
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(rvh1,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            manager->GetSwappedOutRenderViewHost(rvh1->GetSiteInstance()));
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure a swapped out RVH is created in the first opener tab.
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
11415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh));
11425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener1_rvh->IsSwappedOut());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure a swapped out RVH is created in the second opener tab.
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* opener2_rvh = static_cast<TestRenderViewHost*>(
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener2_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
11475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener2_manager->IsRVHOnSwappedOutList(opener2_rvh));
11485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener2_rvh->IsSwappedOut());
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a cross-BrowsingInstance URL.
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kChromeUrl);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh3 = test_rvh();
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(rvh1->GetSiteInstance(), rvh3->GetSiteInstance());
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(rvh1->GetSiteInstance()->IsRelatedSiteInstance(
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   rvh3->GetSiteInstance()));
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No scripting is allowed across BrowsingInstances, so we should not create
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // swapped out RVHs for the opener chain in this case.
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost(
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   rvh3->GetSiteInstance()));
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(opener2_manager->GetSwappedOutRenderViewHost(
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   rvh3->GetSiteInstance()));
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Test that a page can disown the opener of the WebContents.
116603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, DisownOpener) {
116703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
116803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
116903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
117003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to an initial URL.
117103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
117203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh1 = main_test_rfh();
117303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
117403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a new tab and simulate having it be the opener for the main tab.
117503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
117603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TestWebContents::Create(browser_context(), rfh1->GetSiteInstance()));
117703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->SetOpener(opener1.get());
117803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(contents()->HasOpener());
117903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
118003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to a cross-site URL (different SiteInstance but same
118103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // BrowsingInstance).
118203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
118303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh2 = main_test_rfh();
118403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance());
118503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
118603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Disown the opener from rfh2.
118703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh2->DidDisownOpener();
118803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
118903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Ensure the opener is cleared.
119003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(contents()->HasOpener());
119103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
119203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
119303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Test that a page can disown a same-site opener of the WebContents.
119403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, DisownSameSiteOpener) {
119503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
119603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
119703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to an initial URL.
119803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
119903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh1 = main_test_rfh();
120003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
120103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a new tab and simulate having it be the opener for the main tab.
120203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
120303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TestWebContents::Create(browser_context(), rfh1->GetSiteInstance()));
120403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->SetOpener(opener1.get());
120503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(contents()->HasOpener());
120603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
120703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Disown the opener from rfh1.
120803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh1->DidDisownOpener();
120903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
121003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Ensure the opener is cleared even if it is in the same process.
121103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(contents()->HasOpener());
121203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
121303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
121403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Test that a page can disown the opener just as a cross-process navigation is
121503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// in progress.
121603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, DisownOpenerDuringNavigation) {
121703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
121803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
121903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
122003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to an initial URL.
122103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
122203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh1 = main_test_rfh();
122303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
122403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a new tab and simulate having it be the opener for the main tab.
122503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
122603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TestWebContents::Create(browser_context(), rfh1->GetSiteInstance()));
122703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->SetOpener(opener1.get());
122803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(contents()->HasOpener());
122903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
123003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to a cross-site URL (different SiteInstance but same
123103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // BrowsingInstance).
123203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
123303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh2 = main_test_rfh();
123403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance());
123503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
123603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Start a back navigation so that rfh1 becomes the pending RFH.
123703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->GetController().GoBack();
123803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
123903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
124003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Disown the opener from rfh2.
124103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh2->DidDisownOpener();
124203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
124303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Ensure the opener is cleared.
124403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(contents()->HasOpener());
124503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
124603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The back navigation commits.
124703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
124803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
124903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
125003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Ensure the opener is still cleared.
125103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(contents()->HasOpener());
125203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
125303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
125403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Test that a page can disown the opener just after a cross-process navigation
125503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// commits.
125603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, DisownOpenerAfterNavigation) {
125703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
125803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
125903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
126003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to an initial URL.
126103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
126203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh1 = main_test_rfh();
126303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
126403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a new tab and simulate having it be the opener for the main tab.
126503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
126603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TestWebContents::Create(browser_context(), rfh1->GetSiteInstance()));
126703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->SetOpener(opener1.get());
126803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(contents()->HasOpener());
126903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
127003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to a cross-site URL (different SiteInstance but same
127103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // BrowsingInstance).
127203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl2);
127303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh2 = main_test_rfh();
127403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance());
127503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
127603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Commit a back navigation before the DidDisownOpener message arrives.
127703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // rfh1 will be kept alive because of the opener tab.
127803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->GetController().GoBack();
127903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
128003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
128103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
128203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
128303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Disown the opener from rfh2.
128403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh2->DidDisownOpener();
128503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(contents()->HasOpener());
128603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
128703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Test that we clean up swapped out RenderViewHosts when a process hosting
12897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// those associated RenderViews crashes. http://crbug.com/258993
1290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, CleanUpSwappedOutRVHOnProcessCrash) {
12917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL kUrl1("http://www.google.com/");
1292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
12937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate to an initial URL.
12957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->NavigateAndCommit(kUrl1);
12967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestRenderViewHost* rvh1 = test_rvh();
12977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Create a new tab as an opener for the main tab.
12997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<TestWebContents> opener1(
13007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      TestWebContents::Create(browser_context(), rvh1->GetSiteInstance()));
1301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManager* opener1_manager =
13027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      opener1->GetRenderManagerForTesting();
13037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  contents()->SetOpener(opener1.get());
13047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure the new opener RVH is considered live.
13060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  opener1_manager->current_host()->CreateRenderView(
1307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::string16(), -1, MSG_ROUTING_NONE, -1, false);
13081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(opener1_manager->current_host()->IsRenderViewLive());
13091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(opener1_manager->current_frame_host()->IsRenderFrameLive());
1310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Use a cross-process navigation in the opener to swap out the old RVH.
13127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost(
13137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      rvh1->GetSiteInstance()));
1314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  opener1->NavigateAndCommit(kUrl2);
13157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(opener1_manager->GetSwappedOutRenderViewHost(
13167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      rvh1->GetSiteInstance()));
13177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Fake a process crash.
13197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RenderProcessHost::RendererClosedDetails details(
13207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      rvh1->GetProcess()->GetHandle(),
13217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::TERMINATION_STATUS_PROCESS_CRASHED,
13227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      0);
13237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  NotificationService::current()->Notify(
13247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTIFICATION_RENDERER_PROCESS_CLOSED,
13257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      Source<RenderProcessHost>(rvh1->GetProcess()),
13267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      Details<RenderProcessHost::RendererClosedDetails>(&details));
1327fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  rvh1->set_render_view_created(false);
13287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Ensure that the swapped out RenderViewHost has been deleted.
13307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost(
13317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      rvh1->GetSiteInstance()));
1332fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
1333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Reload the initial tab. This should recreate the opener's swapped out RVH
1334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // in the original SiteInstance.
1335fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  contents()->GetController().Reload(true);
1336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(opener1_manager->GetSwappedOutRenderViewHost(
1337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                rvh1->GetSiteInstance())->GetRoutingID(),
1338fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch            test_rvh()->opener_route_id());
13397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that RenderViewHosts created for WebUI navigations are properly
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// granted WebUI bindings even if an unprivileged swapped out RenderViewHost
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is in the same process (http://crbug.com/79918).
1344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, EnableWebUIWithSwappedOutOpener) {
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_should_create_webui(true);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kSettingsUrl("chrome://chrome/settings");
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kPluginUrl("chrome://plugins");
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to an initial WebUI URL.
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kSettingsUrl);
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the RVH has WebUI bindings.
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh1 = test_rvh();
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(rvh1->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new tab and simulate it being the opener for the main
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab.  It should be in the same SiteInstance.
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> opener1(
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), rvh1->GetSiteInstance()));
1360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderFrameHostManager* opener1_manager =
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener1->GetRenderManagerForTesting();
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetOpener(opener1.get());
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a different WebUI URL (different SiteInstance, same
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BrowsingInstance).
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(kPluginUrl);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh2 = test_rvh();
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(rvh1->GetSiteInstance(), rvh2->GetSiteInstance());
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(rvh1->GetSiteInstance()->IsRelatedSiteInstance(
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  rvh2->GetSiteInstance()));
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure a swapped out RVH is created in the first opener tab.
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh));
13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(opener1_rvh->IsSwappedOut());
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the new RVH has WebUI bindings.
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(rvh2->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we reuse the same guest SiteInstance if we navigate across sites.
1383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GURL guest_url(std::string(kGuestScheme).append("://abc123"));
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance =
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SiteInstance::CreateForURL(browser_context(), guest_url);
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> web_contents(
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestWebContents::Create(browser_context(), instance));
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host;
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1) The first navigation. --------------------------
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry1(
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(),
14001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false /* is_renderer_init */);
14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host = manager->Navigate(entry1);
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The RenderFrameHost created in Init will be reused.
14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(host == manager->current_frame_host());
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
14075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(manager->current_frame_host()->GetSiteInstance(), instance);
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
1410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit to SiteInstance should be delayed until RenderView commit.
14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(host);
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSite());
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2) Navigate to a different domain. -------------------------
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Guests stay in the same process on navigation.
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org");
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl entry2(
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl2,
1422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Referrer(kUrl1, blink::WebReferrerPolicyDefault),
14231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_LINK,
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true /* is_renderer_init */);
14255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host = manager->Navigate(entry2);
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The RenderFrameHost created in Init will be reused.
14285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit.
1432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
14335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(host);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<SiteInstanceImpl*>(host->GetSiteInstance()),
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test that we cancel a pending RVH if we close the tab while it's pending.
14404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// http://crbug.com/294697.
1441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
14424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestNotificationTracker notifications;
14434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SiteInstance* instance = SiteInstance::Create(browser_context());
14454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BeforeUnloadFiredWebContentsDelegate delegate;
14474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<TestWebContents> web_contents(
14484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      TestWebContents::Create(browser_context(), instance));
14494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_contents->SetDelegate(&delegate);
14504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notifications.ListenFor(NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
14514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          Source<WebContents>(web_contents.get()));
14524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
14544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 1) The first navigation. --------------------------
14564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
14574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
1458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             Referrer(), base::string16() /* title */,
14591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             ui::PAGE_TRANSITION_TYPED,
14604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             false /* is_renderer_init */);
14615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host = manager->Navigate(entry1);
14624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The RenderFrameHost created in Init will be reused.
14645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
14664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should observe a notification.
14684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(
14694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED));
14704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notifications.Reset();
14714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Commit.
1473effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager->DidNavigateFrame(host);
14744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Commit to SiteInstance should be delayed until RenderFrame commits.
14765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
14784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      HasSite());
14794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->SetSite(kUrl1);
14804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 2) Cross-site navigate to next site. -------------------------
14824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL kUrl2("http://www.example.com");
14834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigationEntryImpl entry2(
14844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NULL /* instance */, -1 /* page_id */, kUrl2, Referrer(),
14851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
14864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      false /* is_renderer_init */);
14875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHostImpl* host2 = manager->Navigate(entry2);
14884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new RenderFrameHost should be created.
14905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(host2, manager->pending_frame_host());
14914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_NE(host2, host);
14924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
14945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
14955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host2, manager->pending_frame_host());
14964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 3) Close the tab. -------------------------
14984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
14995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          Source<RenderWidgetHost>(host2->render_view_host()));
1500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  manager->OnBeforeUnloadACK(false, true, base::TimeTicks());
15014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(
15034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED));
15045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager->pending_frame_host());
15055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(host, manager->current_frame_host());
15065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
15075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
150803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests that the RenderFrameHost is properly deleted when the SwapOutACK is
150903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// received.  (SwapOut and the corresponding ACK always occur after commit.)
151003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Also tests that an early SwapOutACK is properly ignored.
151103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) {
15125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
15135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
15145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigate to the first page.
15165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
15176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
15186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
15196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigate to new site, simulating onbeforeunload approval.
15231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller().LoadURL(
15241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
15255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
15266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetMainFrame()->OnMessageReceived(
1527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
15285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
15296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
15325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
153303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Simulate the swap out ack, unexpectedly early (before commit).  It should
153403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // have no effect.
153503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rfh1->OnSwappedOut(false);
15365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
153703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The new page commits.
15411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED);
15425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
15436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(rfh2, contents()->GetMainFrame());
15446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
15456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh2->GetRenderViewHost()->rvh_state());
15476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN,
15486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Simulate the swap out ack.
15516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  rfh1->OnSwappedOut(false);
15525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // rfh1 should have been deleted.
1554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(rvh_deleted_observer.deleted());
15556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  rfh1 = NULL;
15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests that the RenderFrameHost is properly swapped out when the SwapOut ACK
155903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// is received.  (SwapOut and the corresponding ACK always occur after commit.)
156003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest, SwapOutFrameAfterSwapOutACK) {
15615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL kUrl1("http://www.google.com/");
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL kUrl2("http://www.chromium.org/");
15635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigate to the first page.
15655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
15666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
15676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
15686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Increment the number of active views in SiteInstanceImpl so that rfh1 is
15725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // not deleted on swap out.
15735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static_cast<SiteInstanceImpl*>(
15746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      rfh1->GetSiteInstance())->increment_active_view_count();
15755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigate to new site, simulating onbeforeunload approval.
15771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller().LoadURL(
15781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
15795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
15806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetMainFrame()->OnMessageReceived(
1581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
15825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
158303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
158503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
15865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The new page commits.
15881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED);
15895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
15906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(rfh2, contents()->GetMainFrame());
15916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
15926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
15936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh2->GetRenderViewHost()->rvh_state());
15946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
15956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
15965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Simulate the swap out ack.
15986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  rfh1->OnSwappedOut(false);
15995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // rfh1 should be swapped out.
1601effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(rvh_deleted_observer.deleted());
16026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(rfh1->GetRenderViewHost()->IsSwappedOut());
1603effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1604effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1605effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Test that the RenderViewHost is properly swapped out if a navigation in the
1606effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// new renderer commits before sending the SwapOut message to the old renderer.
1607effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This simulates a cross-site navigation to a synchronously committing URL
1608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// (e.g., a data URL) and ensures it works properly.
1609effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(RenderFrameHostManagerTest,
1610effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       CommitNewNavigationBeforeSendingSwapOut) {
1611effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const GURL kUrl1("http://www.google.com/");
1612effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const GURL kUrl2("http://www.chromium.org/");
1613effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1614effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Navigate to the first page.
1615effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  contents()->NavigateAndCommit(kUrl1);
16166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
16176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
16186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
16196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
1620effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
16216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Increment the number of active views in SiteInstanceImpl so that rfh1 is
1622effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // not deleted on swap out.
1623effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static_cast<SiteInstanceImpl*>(
16246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      rfh1->GetSiteInstance())->increment_active_view_count();
1625effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1626effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Navigate to new site, simulating onbeforeunload approval.
16271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller().LoadURL(
16281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
1629effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::TimeTicks now = base::TimeTicks::Now();
16306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  rfh1->OnMessageReceived(
1631effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
16336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
1634effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1635effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The new page commits.
16361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED);
1637effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
16386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(rfh2, contents()->GetMainFrame());
16396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
16406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
16416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh2->GetRenderViewHost()->rvh_state());
16426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
16436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            rfh1->GetRenderViewHost()->rvh_state());
1644effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1645effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Simulate the swap out ack.
16466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  rfh1->OnSwappedOut(false);
1647effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
16486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // rfh1 should be swapped out.
1649effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(rvh_deleted_observer.deleted());
16506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(rfh1->GetRenderViewHost()->IsSwappedOut());
16514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
16524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1653a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Test that a RenderFrameHost is properly deleted or swapped out when a
1654a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// cross-site navigation is cancelled.
1655a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(RenderFrameHostManagerTest,
1656a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       CancelPendingProperlyDeletesOrSwaps) {
1657a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const GURL kUrl1("http://www.google.com/");
1658a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const GURL kUrl2("http://www.chromium.org/");
1659a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  RenderFrameHostImpl* pending_rfh = NULL;
1660a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  base::TimeTicks now = base::TimeTicks::Now();
1661a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1662a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Navigate to the first page.
1663a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  contents()->NavigateAndCommit(kUrl1);
1664a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TestRenderViewHost* rvh1 = test_rvh();
1665a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1666a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1667a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Navigate to a new site, starting a cross-site navigation.
16681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller().LoadURL(
16691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
1670a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  {
1671a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    pending_rfh = contents()->GetFrameTree()->root()->render_manager()
1672a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ->pending_frame_host();
1673a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderFrameHostDeletedObserver rvh_deleted_observer(pending_rfh);
1674a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1675a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Cancel the navigation by simulating a declined beforeunload dialog.
16766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    contents()->GetMainFrame()->OnMessageReceived(
1677a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FrameHostMsg_BeforeUnload_ACK(0, false, now, now));
1678a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_FALSE(contents()->cross_navigation_pending());
1679a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1680a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Since the pending RFH is the only one for the new SiteInstance, it should
1681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // be deleted.
1682a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_TRUE(rvh_deleted_observer.deleted());
1683a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
1684a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1685a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Start another cross-site navigation.
16861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller().LoadURL(
16871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
1688a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  {
1689a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    pending_rfh = contents()->GetFrameTree()->root()->render_manager()
1690a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ->pending_frame_host();
1691a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderFrameHostDeletedObserver rvh_deleted_observer(pending_rfh);
1692a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1693a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Increment the number of active views in the new SiteInstance, which will
1694a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // cause the pending RFH to be swapped out instead of deleted.
1695a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    static_cast<SiteInstanceImpl*>(
1696a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        pending_rfh->GetSiteInstance())->increment_active_view_count();
1697a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
16986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    contents()->GetMainFrame()->OnMessageReceived(
1699a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FrameHostMsg_BeforeUnload_ACK(0, false, now, now));
1700a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_FALSE(contents()->cross_navigation_pending());
1701a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_FALSE(rvh_deleted_observer.deleted());
1702a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
1703a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1704a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
170503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// PlzNavigate: Test that a proper NavigationRequest is created by
1706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// BeginNavigation.
1707116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(RenderFrameHostManagerTest, BrowserSideNavigationBeginNavigation) {
1708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const GURL kUrl1("http://www.google.com/");
1709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const GURL kUrl2("http://www.chromium.org/");
1710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const GURL kUrl3("http://www.gmail.com/");
17111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int64 kFirstNavRequestID = 1;
1712116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
171303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // TODO(clamy): we should be enabling browser side navigations here
171403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // when CommitNavigation is properly implemented.
1715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Navigate to the first page.
1716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  contents()->NavigateAndCommit(kUrl1);
1717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
171803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EnableBrowserSideNavigation();
1719116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Add a subframe.
1720116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestRenderFrameHost* subframe_rfh = static_cast<TestRenderFrameHost*>(
1721116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      contents()->GetFrameTree()->AddFrame(
17221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          contents()->GetFrameTree()->root(),
17231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          contents()->GetMainFrame()->GetProcess()->GetID(),
17241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          14, "Child"));
1725116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1726116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Simulate a BeginNavigation IPC on the subframe.
1727116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  subframe_rfh->SendBeginNavigationWithURL(kUrl2);
1728116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NavigationRequest* subframe_request =
172903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      GetNavigationRequestForRenderFrameManager(
1730116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          subframe_rfh->frame_tree_node()->render_manager());
1731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(subframe_request);
173203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(kUrl2, subframe_request->info().navigation_params.url);
1733116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // First party for cookies url should be that of the main frame.
1734116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(
173503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      kUrl1, subframe_request->info().first_party_for_cookies);
173603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(subframe_request->info().is_main_frame);
173703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(subframe_request->info().parent_is_main_frame);
17381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kFirstNavRequestID, subframe_request->navigation_request_id());
1739116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1740116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Simulate a BeginNavigation IPC on the main frame.
17416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetMainFrame()->SendBeginNavigationWithURL(kUrl3);
174203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationRequest* main_request = GetNavigationRequestForRenderFrameManager(
17436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      contents()->GetMainFrame()->frame_tree_node()->render_manager());
1744116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(main_request);
174503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(kUrl3, main_request->info().navigation_params.url);
174603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(kUrl3, main_request->info().first_party_for_cookies);
174703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(main_request->info().is_main_frame);
174803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(main_request->info().parent_is_main_frame);
17491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kFirstNavRequestID + 1, main_request->navigation_request_id());
175003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
175103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
175203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// PlzNavigate: Test that RequestNavigation creates a NavigationRequest and that
175303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// RenderFrameHost is not modified when the navigation commits.
175403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest,
175503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       BrowserSideNavigationRequestNavigationNoLiveRenderer) {
175603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl("http://www.google.com/");
175703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
175803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EnableBrowserSideNavigation();
175903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(main_test_rfh()->render_view_host()->IsRenderViewLive());
176003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->GetController().LoadURL(
17611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
176203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RenderFrameHostManager* render_manager =
176303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      main_test_rfh()->frame_tree_node()->render_manager();
176403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationRequest* main_request =
176503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      GetNavigationRequestForRenderFrameManager(render_manager);
176603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // A NavigationRequest should have been generated.
176703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(main_request != NULL);
176803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RenderFrameHostImpl* rfh = main_test_rfh();
176903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
177003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Now commit the same url.
177103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationBeforeCommitInfo commit_info;
177203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  commit_info.navigation_url = kUrl;
17731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  commit_info.navigation_request_id = main_request->navigation_request_id();
177403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  render_manager->CommitNavigation(commit_info);
177503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  main_request = GetNavigationRequestForRenderFrameManager(render_manager);
177603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The main RFH should not have been changed, and the renderer should have
17781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // been initialized.
177903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(rfh, main_test_rfh());
17801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(main_test_rfh()->render_view_host()->IsRenderViewLive());
178103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
178203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
178303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// PlzNavigate: Test that a new RenderFrameHost is created when doing a cross
178403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// site navigation.
178503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RenderFrameHostManagerTest,
178603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       BrowserSideNavigationCrossSiteNavigation) {
178703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl1("http://www.chromium.org/");
178803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GURL kUrl2("http://www.google.com/");
178903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
179003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // TODO(clamy): we should be enabling browser side navigations here
179103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // when CommitNavigation is properly implemented.
179203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to the first page.
179303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  contents()->NavigateAndCommit(kUrl1);
179403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestRenderViewHost* rvh1 = test_rvh();
179503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
179603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RenderFrameHostImpl* rfh = main_test_rfh();
179703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RenderFrameHostManager* render_manager =
179803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      main_test_rfh()->frame_tree_node()->render_manager();
179903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
180003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EnableBrowserSideNavigation();
180103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Navigate to a different site.
180203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  main_test_rfh()->SendBeginNavigationWithURL(kUrl2);
180303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationRequest* main_request =
180403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      GetNavigationRequestForRenderFrameManager(render_manager);
180503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(main_request);
180603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
180703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NavigationBeforeCommitInfo commit_info;
180803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  commit_info.navigation_url = kUrl2;
18091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  commit_info.navigation_request_id = main_request->navigation_request_id();
181003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  render_manager->CommitNavigation(commit_info);
181103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(main_test_rfh(), rfh);
18121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(main_test_rfh()->render_view_host()->IsRenderViewLive());
18131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
18141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// PlzNavigate: Test that a navigation commit is ignored if another request has
18161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// been issued in the meantime.
18171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(carlosk): add checks to assert that the cancel call was sent to
18181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// ResourceDispatcherHost in the IO thread by extending
18191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// ResourceDispatcherHostDelegate (like in cross_site_transfer_browsertest.cc
18201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// and plugin_browsertest.cc).
18211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RenderFrameHostManagerTest,
18221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       BrowserSideNavigationIgnoreStaleNavigationCommit) {
18231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL kUrl0("http://www.wikipedia.org/");
18241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL kUrl0_site = SiteInstance::GetSiteForURL(browser_context(), kUrl0);
18251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL kUrl1("http://www.chromium.org/");
18261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL kUrl2("http://www.google.com/");
18271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL kUrl2_site = SiteInstance::GetSiteForURL(browser_context(), kUrl2);
18281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Initialization.
18301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  contents()->NavigateAndCommit(kUrl0);
18311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RenderFrameHostManager* render_manager =
18321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      main_test_rfh()->frame_tree_node()->render_manager();
18331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EnableBrowserSideNavigation();
18341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kUrl0_site, main_test_rfh()->GetSiteInstance()->GetSiteURL());
18351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Request navigation to the 1st URL and gather data.
18371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  main_test_rfh()->SendBeginNavigationWithURL(kUrl1);
18381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NavigationRequest* request1 =
18391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetNavigationRequestForRenderFrameManager(render_manager);
18401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(request1);
18411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int64 request_id1 = request1->navigation_request_id();
18421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Request navigation to the 2nd URL and gather more data.
18441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  main_test_rfh()->SendBeginNavigationWithURL(kUrl2);
18451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NavigationRequest* request2 =
18461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetNavigationRequestForRenderFrameManager(render_manager);
18471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(request2);
18481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int64 request_id2 = request2->navigation_request_id();
18491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_NE(request_id1, request_id2);
18501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Confirms that a stale commit is ignored by the RHFM.
18521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NavigationBeforeCommitInfo nbc_info;
18531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  nbc_info.navigation_url = kUrl1;
18541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  nbc_info.navigation_request_id = request_id1;
18551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  render_manager->CommitNavigation(nbc_info);
18561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kUrl0_site, main_test_rfh()->GetSiteInstance()->GetSiteURL());
18571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Confirms that a valid, request-matching commit is correctly processed.
18591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  nbc_info.navigation_url = kUrl2;
18601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  nbc_info.navigation_request_id = request_id2;
18611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  render_manager->CommitNavigation(nbc_info);
18621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kUrl2_site, main_test_rfh()->GetSiteInstance()->GetSiteURL());
1863116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1864116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1866