blob: 66c0ca9024d94a1f992d8ef583406a3b594d6f54 [file] [log] [blame]
// 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_INTERSTITIAL_PAGE_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_IMPL_H_
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/renderer_preferences.h"
#include "url/gurl.h"
namespace content {
class NavigationEntry;
class NavigationControllerImpl;
class RenderViewHostImpl;
class RenderWidgetHostView;
class WebContentsView;
class WebContentsImpl;
enum ResourceRequestAction {
BLOCK,
RESUME,
CANCEL
};
class CONTENT_EXPORT InterstitialPageImpl
: public NON_EXPORTED_BASE(InterstitialPage),
public NotificationObserver,
public WebContentsObserver,
public RenderViewHostDelegate,
public RenderWidgetHostDelegate {
public:
// The different state of actions the user can take in an interstitial.
enum ActionState {
NO_ACTION, // No action has been taken yet.
PROCEED_ACTION, // "Proceed" was selected.
DONT_PROCEED_ACTION // "Don't proceed" was selected.
};
InterstitialPageImpl(WebContents* web_contents,
RenderWidgetHostDelegate* render_widget_host_delegate,
bool new_navigation,
const GURL& url,
InterstitialPageDelegate* delegate);
virtual ~InterstitialPageImpl();
// InterstitialPage implementation:
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual void DontProceed() OVERRIDE;
virtual void Proceed() OVERRIDE;
virtual RenderViewHost* GetRenderViewHostForTesting() const OVERRIDE;
virtual InterstitialPageDelegate* GetDelegateForTesting() OVERRIDE;
virtual void DontCreateViewForTesting() OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void Focus() OVERRIDE;
// Allows the user to navigate away by disabling the interstitial, canceling
// the pending request, and unblocking the hidden renderer. The interstitial
// will stay visible until the navigation completes.
void CancelForNavigation();
// Focus the first (last if reverse is true) element in the interstitial page.
// Called when tab traversing.
void FocusThroughTabTraversal(bool reverse);
RenderWidgetHostView* GetView();
// See description above field.
void set_reload_on_dont_proceed(bool value) {
reload_on_dont_proceed_ = value;
}
bool reload_on_dont_proceed() const { return reload_on_dont_proceed_; }
#if defined(OS_ANDROID)
// Android shares a single platform window for all tabs, so we need to expose
// the RenderViewHost to properly route gestures to the interstitial.
RenderViewHost* GetRenderViewHost() const;
#endif
protected:
// NotificationObserver method:
virtual void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) OVERRIDE;
// WebContentsObserver implementation:
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
virtual void NavigationEntryCommitted(
const LoadCommittedDetails& load_details) OVERRIDE;
// RenderViewHostDelegate implementation:
virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE;
virtual const GURL& GetURL() const OVERRIDE;
virtual void RenderViewTerminated(RenderViewHost* render_view_host,
base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void DidNavigate(
RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
virtual void UpdateTitle(RenderViewHost* render_view_host,
int32 page_id,
const string16& title,
base::i18n::TextDirection title_direction) OVERRIDE;
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE;
virtual WebPreferences GetWebkitPrefs() OVERRIDE;
virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE;
virtual void CreateNewWindow(
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) OVERRIDE;
virtual void CreateNewWidget(int route_id,
WebKit::WebPopupType popup_type) OVERRIDE;
virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE;
virtual void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture) OVERRIDE;
virtual void ShowCreatedWidget(int route_id,
const gfx::Rect& initial_pos) OVERRIDE;
virtual void ShowCreatedFullscreenWidget(int route_id) OVERRIDE;
virtual SessionStorageNamespace* GetSessionStorageNamespace(
SiteInstance* instance) OVERRIDE;
virtual FrameTree* GetFrameTree() OVERRIDE;
// RenderWidgetHostDelegate implementation:
virtual void RenderWidgetDeleted(
RenderWidgetHostImpl* render_widget_host) OVERRIDE;
virtual bool PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) OVERRIDE;
virtual void HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) OVERRIDE;
#if defined(OS_WIN) && defined(USE_AURA)
virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE;
#endif
bool enabled() const { return enabled_; }
WebContents* web_contents() const;
const GURL& url() const { return url_; }
// Creates the RenderViewHost containing the interstitial content.
// Overriden in unit tests.
virtual RenderViewHost* CreateRenderViewHost();
// Creates the WebContentsView that shows the interstitial RVH.
// Overriden in unit tests.
virtual WebContentsView* CreateWebContentsView();
// Notification magic.
NotificationRegistrar notification_registrar_;
private:
class InterstitialPageRVHDelegateView;
// Disable the interstitial:
// - if it is not yet showing, then it won't be shown.
// - any command sent by the RenderViewHost will be ignored.
void Disable();
// Shutdown the RVH. We will be deleted by the time this method returns.
void Shutdown(RenderViewHostImpl* render_view_host);
void OnNavigatingAwayOrTabClosing();
// Executes the passed action on the ResourceDispatcher (on the IO thread).
// Used to block/resume/cancel requests for the RenderViewHost hidden by this
// interstitial.
void TakeActionOnResourceDispatcher(ResourceRequestAction action);
// The contents in which we are displayed. This is valid until Hide is
// called, at which point it will be set to NULL because the WebContents
// itself may be deleted.
WebContents* web_contents_;
// The NavigationController for the content this page is being displayed over.
NavigationControllerImpl* controller_;
// Delegate for dispatching keyboard events and accessing the native view.
RenderWidgetHostDelegate* render_widget_host_delegate_;
// The URL that is shown when the interstitial is showing.
GURL url_;
// Whether this interstitial is shown as a result of a new navigation (in
// which case a transient navigation entry is created).
bool new_navigation_;
// Whether we should discard the pending navigation entry when not proceeding.
// This is to deal with cases where |new_navigation_| is true but a new
// pending entry was created since this interstitial was shown and we should
// not discard it.
bool should_discard_pending_nav_entry_;
// If true and the user chooses not to proceed the target NavigationController
// is reloaded. This is used when two NavigationControllers are merged
// (CopyStateFromAndPrune).
// The default is false.
bool reload_on_dont_proceed_;
// Whether this interstitial is enabled. See Disable() for more info.
bool enabled_;
// Whether the Proceed or DontProceed methods have been called yet.
ActionState action_taken_;
// The RenderViewHost displaying the interstitial contents. This is valid
// until Hide is called, at which point it will be set to NULL, signifying
// that shutdown has started.
RenderViewHostImpl* render_view_host_;
// The frame tree structure of the current page.
FrameTree frame_tree_;
// The IDs for the Render[View|Process]Host hidden by this interstitial.
int original_child_id_;
int original_rvh_id_;
// Whether or not we should change the title of the contents when hidden (to
// revert it to its original value).
bool should_revert_web_contents_title_;
// Whether or not the contents was loading resources when the interstitial was
// shown. We restore this state if the user proceeds from the interstitial.
bool web_contents_was_loading_;
// Whether the ResourceDispatcherHost has been notified to cancel/resume the
// resource requests blocked for the RenderViewHost.
bool resource_dispatcher_host_notified_;
// The original title of the contents that should be reverted to when the
// interstitial is hidden.
string16 original_web_contents_title_;
// Our RenderViewHostViewDelegate, necessary for accelerators to work.
scoped_ptr<InterstitialPageRVHDelegateView> rvh_delegate_view_;
// Settings passed to the renderer.
mutable RendererPreferences renderer_preferences_;
bool create_view_;
scoped_ptr<InterstitialPageDelegate> delegate_;
base::WeakPtrFactory<InterstitialPageImpl> weak_ptr_factory_;
scoped_refptr<SessionStorageNamespace> session_storage_namespace_;
DISALLOW_COPY_AND_ASSIGN(InterstitialPageImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_IMPL_H_