// 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_INTERSTITIAL_PAGE_H_ #define CHROME_BROWSER_TAB_CONTENTS_INTERSTITIAL_PAGE_H_ #pragma once #include #include #include "base/process_util.h" #include "base/scoped_ptr.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/renderer_preferences.h" #include "gfx/size.h" #include "googleurl/src/gurl.h" class NavigationEntry; class TabContents; class TabContentsView; // This class is a base class for interstitial pages, pages that show some // informative message asking for user validation before reaching the target // page. (Navigating to a page served over bad HTTPS or a page containing // malware are typical cases where an interstitial is required.) // // If specified in its constructor, this class creates a navigation entry so // that when the interstitial shows, the current entry is the target URL. // // InterstitialPage instances take care of deleting themselves when closed // through a navigation, the TabContents closing them or the tab containing them // being closed. enum ResourceRequestAction { BLOCK, RESUME, CANCEL }; class InterstitialPage : public NotificationObserver, public RenderViewHostDelegate { 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. }; // Creates an interstitial page to show in |tab|. |new_navigation| should be // set to true when the interstitial is caused by loading a new page, in which // case a temporary navigation entry is created with the URL |url| and // added to the navigation controller (so the interstitial page appears as a // new navigation entry). |new_navigation| should be false when the // interstitial was triggered by a loading a sub-resource in a page. InterstitialPage(TabContents* tab, bool new_navigation, const GURL& url); virtual ~InterstitialPage(); // Shows the interstitial page in the tab. virtual void Show(); // Hides the interstitial page. Warning: this deletes the InterstitialPage. void Hide(); // Retrieves the InterstitialPage if any associated with the specified // |tab_contents| (used by ui tests). static InterstitialPage* GetInterstitialPage(TabContents* tab_contents); // Sub-classes should return the HTML that should be displayed in the page. virtual std::string GetHTMLContents(); // Reverts to the page showing before the interstitial. // Sub-classes should call this method when the user has chosen NOT to proceed // to the target URL. // Warning: if |new_navigation| was set to true in the constructor, 'this' // will be deleted when this method returns. virtual void DontProceed(); // Sub-classes should call this method when the user has chosen to proceed to // the target URL. // Warning: 'this' has been deleted when this method returns. virtual void Proceed(); // 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(); // Sizes the RenderViewHost showing the actual interstitial page contents. void SetSize(const gfx::Size& size); ActionState action_taken() const { return action_taken_; } // Sets the focus to the interstitial. void Focus(); // Focus the first (last if reverse is true) element in the interstitial page. // Called when tab traversing. void FocusThroughTabTraversal(bool reverse); virtual ViewType::Type GetRenderViewType() const; virtual int GetBrowserWindowID() const; // 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_; } virtual void UpdateInspectorSetting(const std::string& key, const std::string& value); virtual void ClearInspectorSettings(); protected: // NotificationObserver method: virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); // RenderViewHostDelegate implementation: virtual View* GetViewDelegate(); virtual const GURL& GetURL() const; virtual void RenderViewGone(RenderViewHost* render_view_host, base::TerminationStatus status, int error_code); virtual void DidNavigate(RenderViewHost* render_view_host, const ViewHostMsg_FrameNavigate_Params& params); virtual void UpdateTitle(RenderViewHost* render_view_host, int32 page_id, const std::wstring& title); virtual void DomOperationResponse(const std::string& json_string, int automation_id); virtual RendererPreferences GetRendererPrefs(Profile* profile) const; // Invoked when the page sent a command through DOMAutomation. virtual void CommandReceived(const std::string& command) {} // Invoked with the NavigationEntry that is going to be added to the // navigation controller. // Gives an opportunity to sub-classes to set states on the |entry|. // Note that this is only called if the InterstitialPage was constructed with // |create_navigation_entry| set to true. virtual void UpdateEntry(NavigationEntry* entry) {} TabContents* tab() const { return tab_; } const GURL& url() const { return url_; } RenderViewHost* render_view_host() const { return render_view_host_; } // Creates the RenderViewHost containing the interstitial content. // Overriden in unit tests. virtual RenderViewHost* CreateRenderViewHost(); // Creates the TabContentsView that shows the interstitial RVH. // Overriden in unit tests. virtual TabContentsView* CreateTabContentsView(); private: // AutomationProvider needs access to Proceed and DontProceed to simulate // user actions. friend class AutomationProvider; class InterstitialPageRVHViewDelegate; // Initializes tab_to_interstitial_page_ in a thread-safe manner. // Should be called before accessing tab_to_interstitial_page_. static void InitInterstitialPageMap(); // 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(); // 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 tab in which we are displayed. TabContents* tab_; // 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_; // Notification magic. NotificationRegistrar notification_registrar_; // The RenderViewHost displaying the interstitial contents. RenderViewHost* render_view_host_; // 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 tab when hidden (to revert // it to its original value). bool should_revert_tab_title_; // 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 tab that should be reverted to when the // interstitial is hidden. std::wstring original_tab_title_; // Our RenderViewHostViewDelegate, necessary for accelerators to work. scoped_ptr rvh_view_delegate_; // We keep a map of the various blocking pages shown as the UI tests need to // be able to retrieve them. typedef std::map InterstitialPageMap; static InterstitialPageMap* tab_to_interstitial_page_; // Settings passed to the renderer. RendererPreferences renderer_preferences_; DISALLOW_COPY_AND_ASSIGN(InterstitialPage); }; #endif // CHROME_BROWSER_TAB_CONTENTS_INTERSTITIAL_PAGE_H_