summaryrefslogtreecommitdiffstats
path: root/content/browser/frame_host/render_frame_host_manager.h
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/frame_host/render_frame_host_manager.h')
-rw-r--r--content/browser/frame_host/render_frame_host_manager.h406
1 files changed, 406 insertions, 0 deletions
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
new file mode 100644
index 0000000..78ca04a
--- /dev/null
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -0,0 +1,406 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
+#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/browser/site_instance_impl.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/common/referrer.h"
+
+
+namespace content {
+class BrowserContext;
+class InterstitialPageImpl;
+class NavigationControllerImpl;
+class NavigationEntry;
+class NavigationEntryImpl;
+class RenderFrameHostManagerTest;
+class RenderViewHost;
+class RenderViewHostImpl;
+class RenderWidgetHostDelegate;
+class RenderWidgetHostView;
+class TestWebContents;
+class WebUIImpl;
+
+// Manages RenderFrameHosts for a FrameTreeNode. This class acts as a state
+// machine to make cross-process navigations in a frame possible.
+class CONTENT_EXPORT RenderFrameHostManager
+ : public RenderViewHostDelegate::RendererManagement,
+ public NotificationObserver {
+ public:
+ // Functions implemented by our owner that we need.
+ //
+ // TODO(brettw) Clean this up! These are all the functions in WebContentsImpl
+ // that are required to run this class. The design should probably be better
+ // such that these are more clear.
+ //
+ // There is additional complexity that some of the functions we need in
+ // WebContentsImpl are inherited and non-virtual. These are named with
+ // "RenderManager" so that the duplicate implementation of them will be clear.
+ class CONTENT_EXPORT Delegate {
+ public:
+ // Initializes the given renderer if necessary and creates the view ID
+ // corresponding to this view host. If this method is not called and the
+ // process is not shared, then the WebContentsImpl will act as though the
+ // renderer is not running (i.e., it will render "sad tab"). This method is
+ // automatically called from LoadURL.
+ //
+ // If you are attaching to an already-existing RenderView, you should call
+ // InitWithExistingID.
+ virtual bool CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host, int opener_route_id) = 0;
+ virtual void BeforeUnloadFiredFromRenderManager(
+ bool proceed, const base::TimeTicks& proceed_time,
+ bool* proceed_to_fire_unload) = 0;
+ virtual void RenderProcessGoneFromRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void UpdateRenderViewSizeForRenderManager() = 0;
+ virtual void CancelModalDialogsForRenderManager() = 0;
+ virtual void NotifySwappedFromRenderManager(
+ RenderViewHost* old_host, RenderViewHost* new_host) = 0;
+ virtual NavigationControllerImpl&
+ GetControllerForRenderManager() = 0;
+
+ // Create swapped out RenderViews in the given SiteInstance for each tab in
+ // the opener chain of this tab, if any. This allows the current tab to
+ // make cross-process script calls to its opener(s). Returns the route ID
+ // of the immediate opener, if one exists (otherwise MSG_ROUTING_NONE).
+ virtual int CreateOpenerRenderViewsForRenderManager(
+ SiteInstance* instance) = 0;
+
+ // Creates a WebUI object for the given URL if one applies. Ownership of the
+ // returned pointer will be passed to the caller. If no WebUI applies,
+ // returns NULL.
+ virtual WebUIImpl* CreateWebUIForRenderManager(const GURL& url) = 0;
+
+ // Returns the navigation entry of the current navigation, or NULL if there
+ // is none.
+ virtual NavigationEntry*
+ GetLastCommittedNavigationEntryForRenderManager() = 0;
+
+ // Returns true if the location bar should be focused by default rather than
+ // the page contents. The view calls this function when the tab is focused
+ // to see what it should do.
+ virtual bool FocusLocationBarByDefault() = 0;
+
+ // Focuses the location bar.
+ virtual void SetFocusToLocationBar(bool select_all) = 0;
+
+ // Creates a view and sets the size for the specified RVH.
+ virtual void CreateViewAndSetSizeForRVH(RenderViewHost* rvh) = 0;
+
+ // Returns true if views created for this delegate should be created in a
+ // hidden state.
+ virtual bool IsHidden() = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ // All three delegate pointers must be non-NULL and are not owned by this
+ // class. They must outlive this class. The RenderViewHostDelegate and
+ // RenderWidgetHostDelegate are what will be installed into all
+ // RenderViewHosts that are created.
+ //
+ // You must call Init() before using this class.
+ RenderFrameHostManager(
+ RenderViewHostDelegate* render_view_delegate,
+ RenderWidgetHostDelegate* render_widget_delegate,
+ Delegate* delegate);
+ virtual ~RenderFrameHostManager();
+
+ // For arguments, see WebContentsImpl constructor.
+ void Init(BrowserContext* browser_context,
+ SiteInstance* site_instance,
+ int routing_id,
+ int main_frame_routing_id);
+
+ // Returns the currently active RenderViewHost.
+ //
+ // This will be non-NULL between Init() and Shutdown(). You may want to NULL
+ // check it in many cases, however. Windows can send us messages during the
+ // destruction process after it has been shut down.
+ RenderViewHostImpl* current_host() const;
+
+ // Returns the view associated with the current RenderViewHost, or NULL if
+ // there is no current one.
+ RenderWidgetHostView* GetRenderWidgetHostView() const;
+
+ // Returns the pending render view host, or NULL if there is no pending one.
+ RenderViewHostImpl* pending_render_view_host() const;
+
+ // Returns the current committed Web UI or NULL if none applies.
+ WebUIImpl* web_ui() const { return web_ui_.get(); }
+
+ // Returns the Web UI for the pending navigation, or NULL of none applies.
+ WebUIImpl* pending_web_ui() const {
+ return pending_web_ui_.get() ? pending_web_ui_.get() :
+ pending_and_current_web_ui_.get();
+ }
+
+ // Sets the pending Web UI for the pending navigation, ensuring that the
+ // bindings are appropriate for the given NavigationEntry.
+ void SetPendingWebUI(const NavigationEntryImpl& entry);
+
+ // Called when we want to instruct the renderer to navigate to the given
+ // navigation entry. It may create a new RenderViewHost or re-use an existing
+ // one. The RenderViewHost to navigate will be returned. Returns NULL if one
+ // could not be created.
+ RenderViewHostImpl* Navigate(const NavigationEntryImpl& entry);
+
+ // Instructs the various live views to stop. Called when the user directed the
+ // page to stop loading.
+ void Stop();
+
+ // Notifies the regular and pending RenderViewHosts that a load is or is not
+ // happening. Even though the message is only for one of them, we don't know
+ // which one so we tell both.
+ void SetIsLoading(bool is_loading);
+
+ // Whether to close the tab or not when there is a hang during an unload
+ // handler. If we are mid-crosssite navigation, then we should proceed
+ // with the navigation instead of closing the tab.
+ bool ShouldCloseTabOnUnresponsiveRenderer();
+
+ // The RenderViewHost has been swapped out, so we should resume the pending
+ // network response and allow the pending RenderViewHost to commit.
+ void SwappedOut(RenderViewHost* render_view_host);
+
+ // Called when a renderer's main frame navigates.
+ void DidNavigateMainFrame(RenderViewHost* render_view_host);
+
+ // Called when a renderer sets its opener to null.
+ void DidDisownOpener(RenderViewHost* render_view_host);
+
+ // Helper method to create a RenderViewHost. If |swapped_out| is true, it
+ // will be initially placed on the swapped out hosts list. Otherwise, it
+ // will be used for a pending cross-site navigation.
+ int CreateRenderView(SiteInstance* instance,
+ int opener_route_id,
+ bool swapped_out,
+ bool hidden);
+
+ // Called when a provisional load on the given renderer is aborted.
+ void RendererAbortedProvisionalLoad(RenderViewHost* render_view_host);
+
+ // Sets the passed passed interstitial as the currently showing interstitial.
+ // |interstitial_page| should be non NULL (use the remove_interstitial_page
+ // method to unset the interstitial) and no interstitial page should be set
+ // when there is already a non NULL interstitial page set.
+ void set_interstitial_page(InterstitialPageImpl* interstitial_page) {
+ DCHECK(!interstitial_page_ && interstitial_page);
+ interstitial_page_ = interstitial_page;
+ }
+
+ // Unsets the currently showing interstitial.
+ void remove_interstitial_page() {
+ DCHECK(interstitial_page_);
+ interstitial_page_ = NULL;
+ }
+
+ // Returns the currently showing interstitial, NULL if no interstitial is
+ // showing.
+ InterstitialPageImpl* interstitial_page() const { return interstitial_page_; }
+
+ // RenderViewHostDelegate::RendererManagement implementation.
+ virtual void ShouldClosePage(
+ bool for_cross_site_transition,
+ bool proceed,
+ const base::TimeTicks& proceed_time) OVERRIDE;
+ virtual void OnCrossSiteResponse(
+ RenderViewHost* pending_render_view_host,
+ const GlobalRequestID& global_request_id,
+ bool is_transfer,
+ const std::vector<GURL>& transfer_url_chain,
+ const Referrer& referrer,
+ PageTransition page_transition,
+ int64 frame_id,
+ bool should_replace_current_entry) OVERRIDE;
+
+ // NotificationObserver implementation.
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE;
+
+ // Called when a RenderViewHost is about to be deleted.
+ void RenderViewDeleted(RenderViewHost* rvh);
+
+ // Returns whether the given RenderViewHost is on the list of swapped out
+ // RenderViewHosts.
+ bool IsOnSwappedOutList(RenderViewHost* rvh) const;
+
+ // Returns the swapped out RenderViewHost for the given SiteInstance, if any.
+ RenderViewHostImpl* GetSwappedOutRenderViewHost(SiteInstance* instance);
+
+ // Runs the unload handler in the current page, when we know that a pending
+ // cross-process navigation is going to commit. We may initiate a transfer
+ // to a new process after this completes or times out.
+ void SwapOutOldPage();
+
+ private:
+ friend class RenderFrameHostManagerTest;
+ friend class TestWebContents;
+
+ // Tracks information about a navigation while a cross-process transition is
+ // in progress, in case we need to transfer it to a new RenderViewHost.
+ struct PendingNavigationParams {
+ PendingNavigationParams();
+ PendingNavigationParams(const GlobalRequestID& global_request_id,
+ bool is_transfer,
+ const std::vector<GURL>& transfer_url,
+ Referrer referrer,
+ PageTransition page_transition,
+ int64 frame_id,
+ bool should_replace_current_entry);
+ ~PendingNavigationParams();
+
+ // The child ID and request ID for the pending navigation. Present whether
+ // |is_transfer| is true or false.
+ GlobalRequestID global_request_id;
+
+ // Whether this pending navigation needs to be transferred to another
+ // process than the one it was going to commit in. If so, the
+ // |transfer_url|, |referrer|, and |frame_id| parameters will be set.
+ bool is_transfer;
+
+ // If |is_transfer|, this is the URL chain of the request. The first entry
+ // is the original request URL, and the last entry is the destination URL to
+ // request in the new process.
+ std::vector<GURL> transfer_url_chain;
+
+ // If |is_transfer|, this is the referrer to use for the request in the new
+ // process.
+ Referrer referrer;
+
+ // If |is_transfer|, this is the transition type for the original
+ // navigation.
+ PageTransition page_transition;
+
+ // If |is_transfer|, this is the frame ID to use in RequestTransferURL.
+ int64 frame_id;
+
+ // If |is_transfer|, this is whether the navigation should replace the
+ // current history entry.
+ bool should_replace_current_entry;
+ };
+
+ // Returns whether this tab should transition to a new renderer for
+ // cross-site URLs. Enabled unless we see the --process-per-tab command line
+ // switch. Can be overridden in unit tests.
+ bool ShouldTransitionCrossSite();
+
+ // Returns true if for the navigation from |current_entry| to |new_entry|,
+ // a new SiteInstance and BrowsingInstance should be created (even if we are
+ // in a process model that doesn't usually swap). This forces a process swap
+ // and severs script connections with existing tabs. Cases where this can
+ // happen include transitions between WebUI and regular web pages.
+ // Either of the entries may be NULL.
+ bool ShouldSwapBrowsingInstancesForNavigation(
+ const NavigationEntry* current_entry,
+ const NavigationEntryImpl* new_entry) const;
+
+ // Returns true if it is safe to reuse the current WebUI when navigating from
+ // |current_entry| to |new_entry|.
+ bool ShouldReuseWebUI(
+ const NavigationEntry* current_entry,
+ const NavigationEntryImpl* new_entry) const;
+
+ // Returns an appropriate SiteInstance object for the given NavigationEntry,
+ // possibly reusing the current SiteInstance. If --process-per-tab is used,
+ // this is only called when ShouldSwapBrowsingInstancesForNavigation returns
+ // true.
+ SiteInstance* GetSiteInstanceForEntry(
+ const NavigationEntryImpl& entry,
+ SiteInstance* current_instance,
+ bool force_browsing_instance_swap);
+
+ // Sets up the necessary state for a new RenderViewHost with the given opener.
+ bool InitRenderView(RenderViewHost* render_view_host, int opener_route_id);
+
+ // Sets the pending RenderViewHost/WebUI to be the active one. Note that this
+ // doesn't require the pending render_view_host_ pointer to be non-NULL, since
+ // there could be Web UI switching as well. Call this for every commit.
+ void CommitPending();
+
+ // Shutdown all RenderViewHosts in a SiteInstance. This is called
+ // to shutdown views when all the views in a SiteInstance are
+ // confirmed to be swapped out.
+ void ShutdownRenderViewHostsInSiteInstance(int32 site_instance_id);
+
+ // Helper method to terminate the pending RenderViewHost.
+ void CancelPending();
+
+ RenderViewHostImpl* UpdateRendererStateForNavigate(
+ const NavigationEntryImpl& entry);
+
+ // Called when a renderer process is starting to close. We should not
+ // schedule new navigations in its swapped out RenderViewHosts after this.
+ void RendererProcessClosing(RenderProcessHost* render_process_host);
+
+ // Our delegate, not owned by us. Guaranteed non-NULL.
+ Delegate* delegate_;
+
+ // Whether a navigation requiring different RenderView's is pending. This is
+ // either cross-site request is (in the new process model), or when required
+ // for the view type (like view source versus not).
+ bool cross_navigation_pending_;
+
+ // Implemented by the owner of this class, these delegates are installed into
+ // all the RenderViewHosts that we create.
+ RenderViewHostDelegate* render_view_delegate_;
+ RenderWidgetHostDelegate* render_widget_delegate_;
+
+ // Our RenderView host and its associated Web UI (if any, will be NULL for
+ // non-DOM-UI pages). This object is responsible for all communication with
+ // a child RenderView instance.
+ RenderViewHostImpl* render_view_host_;
+ scoped_ptr<WebUIImpl> web_ui_;
+
+ // A RenderViewHost used to load a cross-site page. This remains hidden
+ // while a cross-site request is pending until it calls DidNavigate. It may
+ // have an associated Web UI, in which case the Web UI pointer will be non-
+ // NULL.
+ //
+ // The |pending_web_ui_| may be non-NULL even when the
+ // |pending_render_view_host_| is NULL. This will happen when we're
+ // transitioning between two Web UI pages: the RVH won't be swapped, so the
+ // pending pointer will be unused, but there will be a pending Web UI
+ // associated with the navigation.
+ RenderViewHostImpl* pending_render_view_host_;
+
+ // Tracks information about any current pending cross-process navigation.
+ scoped_ptr<PendingNavigationParams> pending_nav_params_;
+
+ // If either of these is non-NULL, the pending navigation is to a chrome:
+ // page. The scoped_ptr is used if pending_web_ui_ != web_ui_, the WeakPtr is
+ // used for when they reference the same object. If either is non-NULL, the
+ // other should be NULL.
+ scoped_ptr<WebUIImpl> pending_web_ui_;
+ base::WeakPtr<WebUIImpl> pending_and_current_web_ui_;
+
+ // A map of site instance ID to swapped out RenderViewHosts. This may include
+ // pending_render_view_host_ for navigations to existing entries.
+ typedef base::hash_map<int32, RenderViewHostImpl*> RenderViewHostMap;
+ RenderViewHostMap swapped_out_hosts_;
+
+ // The intersitial page currently shown if any, not own by this class
+ // (the InterstitialPage is self-owned, it deletes itself when hidden).
+ InterstitialPageImpl* interstitial_page_;
+
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_