summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tab_contents/render_view_host_manager.h
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-03 17:32:37 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-03 17:32:37 +0000
commitfd694982d0e1ee8b3e1753d9c48b01c1a633ac27 (patch)
tree5901960deccdcc083ea05c0ecb57921f74017919 /chrome/browser/tab_contents/render_view_host_manager.h
parent87666f9f261e814b56d57cb17a54af01d8aa1227 (diff)
downloadchromium_src-fd694982d0e1ee8b3e1753d9c48b01c1a633ac27.zip
chromium_src-fd694982d0e1ee8b3e1753d9c48b01c1a633ac27.tar.gz
chromium_src-fd694982d0e1ee8b3e1753d9c48b01c1a633ac27.tar.bz2
Move RenderViewHostManager back to tab_contents. Moving it to renderer_host
was a bad idea because of its significant dependencies on NavigationController and NavigationEntry. I'm trying to make renderer_host not depend on tab_contents at all. Remove the dependency on TabContents pointers for notifications from the ResourceDispatcherHost. Instead of having the broadcast code in the ResourceDispatcherHost, I made it call a RenderViewHostDelegate callback. Then TabContents implements the notification, so that it's really from the TabContents. Review URL: http://codereview.chromium.org/150069 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19909 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents/render_view_host_manager.h')
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager.h267
1 files changed, 267 insertions, 0 deletions
diff --git a/chrome/browser/tab_contents/render_view_host_manager.h b/chrome/browser/tab_contents/render_view_host_manager.h
new file mode 100644
index 0000000..e06380c
--- /dev/null
+++ b/chrome/browser/tab_contents/render_view_host_manager.h
@@ -0,0 +1,267 @@
+// Copyright (c) 2009 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 CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_
+#define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_observer.h"
+
+class DOMUI;
+class InterstitialPage;
+class NavigationController;
+class NavigationEntry;
+class Profile;
+class RenderViewHostDelegate;
+class RenderWidgetHostView;
+class SiteInstance;
+
+// Manages RenderViewHosts for a TabContents. Normally there is only one and
+// it is easy to do. But we can also have transitions of processes (and hence
+// RenderViewHosts) that can get complex.
+class RenderViewHostManager : public NotificationObserver {
+ public:
+ // Functions implemented by our owner that we need.
+ //
+ // TODO(brettw) Clean this up! These are all the functions in TabContents 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
+ // TabContents are inherited and non-virtual. These are named with
+ // "RenderManager" so that the duplicate implementation of them will be clear.
+ class Delegate {
+ public:
+ // See tab_contents.h's implementation for more.
+ virtual bool CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void BeforeUnloadFiredFromRenderManager(
+ bool proceed, bool* proceed_to_fire_unload) = 0;
+ virtual void DidStartLoadingFromRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void RenderViewGoneFromRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void UpdateRenderViewSizeForRenderManager() = 0;
+ virtual void NotifySwappedFromRenderManager() = 0;
+ virtual NavigationController& GetControllerForRenderManager() = 0;
+
+ // Creates a DOMUI object for the given URL if one applies. Ownership of the
+ // returned pointer will be passed to the caller. If no DOMUI applies,
+ // returns NULL.
+ virtual DOMUI* CreateDOMUIForRenderManager(const GURL& url) = 0;
+
+ // Returns the navigation entry of the current navigation, or NULL if there
+ // is none.
+ virtual NavigationEntry*
+ GetLastCommittedNavigationEntryForRenderManager() = 0;
+ };
+
+ // Both delegate pointers must be non-NULL and are not owned by this class.
+ // They must outlive this class. The RenderViewHostDelegate is what will be
+ // installed into all RenderViewHosts that are created.
+ //
+ // You must call Init() before using this class.
+ RenderViewHostManager(RenderViewHostDelegate* render_view_delegate,
+ Delegate* delegate);
+ ~RenderViewHostManager();
+
+ // For arguments, see TabContents constructor.
+ void Init(Profile* profile,
+ SiteInstance* site_instance,
+ int routing_id,
+ base::WaitableEvent* modal_dialog_event);
+
+ // Returns the currently actuive 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.
+ RenderViewHost* current_host() const {
+ return render_view_host_;
+ }
+
+ // Returns the view associated with the current RenderViewHost, or NULL if
+ // there is no current one.
+ RenderWidgetHostView* current_view() const {
+ if (!render_view_host_)
+ return NULL;
+ return render_view_host_->view();
+ }
+
+ // Returns the pending render view host, or NULL if there is no pending one.
+ RenderViewHost* pending_render_view_host() const {
+ return pending_render_view_host_;
+ }
+
+ // Returns the current committed DOM UI or NULL if none applies.
+ DOMUI* dom_ui() const { return dom_ui_.get(); }
+
+ // Returns the DOM UI for the pending navigation, or NULL of none applies.
+ DOMUI* pending_dom_ui() const { return pending_dom_ui_.get(); }
+
+ // 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.
+ RenderViewHost* Navigate(const NavigationEntry& 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();
+
+ // Called when a renderer's main frame navigates.
+ void DidNavigateMainFrame(RenderViewHost* render_view_host);
+
+ // Allows the TabContents to react when a cross-site response is ready to be
+ // delivered to a pending RenderViewHost. We must first run the onunload
+ // handler of the old RenderViewHost before we can allow it to proceed.
+ void OnCrossSiteResponse(int new_render_process_host_id,
+ int new_request_id);
+
+ // Notifies that the navigation that initiated a cross-site transition has
+ // been canceled.
+ void CrossSiteNavigationCanceled();
+
+ // Called when a provisional load on the given renderer is aborted.
+ void RendererAbortedProvisionalLoad(RenderViewHost* render_view_host);
+
+ // Actually implements this RenderViewHostDelegate function for the
+ // TabContents.
+ void ShouldClosePage(bool proceed);
+
+ // Forwards the message to the RenderViewHost, which is the original one.
+ void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
+ bool success,
+ const std::wstring& prompt);
+
+ // Forwards this message to the RenderViewHost.
+ void OnJavaScriptMessageBoxWindowDestroyed();
+
+ // 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(InterstitialPage* 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.
+ InterstitialPage* interstitial_page() const {
+ return interstitial_page_;
+ }
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ friend class TestTabContents;
+
+ // 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 the two navigation entries are incompatible in some way
+ // other than site instances. Cases where this can happen include DOM UI
+ // to regular web pages. It will cause us to swap RenderViewHosts (and hence
+ // RenderProcessHosts) even if the site instance would otherwise be the same.
+ // As part of this, we'll also force new SiteInstances and BrowsingInstances.
+ // Either of the entries may be NULL.
+ bool ShouldSwapProcessesForNavigation(
+ const NavigationEntry* cur_entry,
+ const NavigationEntry* new_entry) const;
+
+ // Returns an appropriate SiteInstance object for the given NavigationEntry,
+ // possibly reusing the current SiteInstance.
+ // Never called if --process-per-tab is used.
+ SiteInstance* GetSiteInstanceForEntry(const NavigationEntry& entry,
+ SiteInstance* curr_instance);
+
+ // Helper method to create a pending RenderViewHost for a cross-site
+ // navigation.
+ bool CreatePendingRenderView(SiteInstance* instance);
+
+ // Sets the pending RenderViewHost/DOMUI 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 DOM UI switching as well. Call this for every commit.
+ void CommitPending();
+
+ // Helper method to terminate the pending RenderViewHost.
+ void CancelPending();
+
+ RenderViewHost* UpdateRendererStateForNavigate(const NavigationEntry& entry);
+
+ // 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, this delegate is installed into all
+ // the RenderViewHosts that we create.
+ RenderViewHostDelegate* render_view_delegate_;
+
+ // Our RenderView host and its associated DOM UI (if any, will be NULL for
+ // non-DOM-UI pages). This object is responsible for all communication with
+ // a child RenderView instance.
+ RenderViewHost* render_view_host_;
+ scoped_ptr<DOMUI> dom_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 DOM UI, in which case the DOM UI pointer will be non-
+ // NULL.
+ //
+ // The pending_dom_ui may be non-NULL even when the pending_render_view_host_
+ // is. This will happen when we're transitioning between two DOM UI pages:
+ // the RVH won't be swapped, so the pending pointer will be unused, but there
+ // will be a pending DOM UI associated with the navigation.
+ RenderViewHost* pending_render_view_host_;
+ scoped_ptr<DOMUI> pending_dom_ui_;
+
+ // Records whether the navigation was cancelled, but we are leaving the
+ // pending_render_view_host_ around in consideration of the download system.
+ bool pending_renderer_aborted_;
+
+ // The intersitial page currently shown if any, not own by this class
+ // (the InterstitialPage is self-owned, it deletes itself when hidden).
+ InterstitialPage* interstitial_page_;
+
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager);
+};
+
+// The "details" for a NOTIFY_RENDER_VIEW_HOST_CHANGED notification. The old
+// host can be NULL when the first RenderViewHost is set.
+struct RenderViewHostSwitchedDetails {
+ RenderViewHost* old_host;
+ RenderViewHost* new_host;
+};
+
+#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_