1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_WEB_CONTENTS_INTERSTITIAL_PAGE_IMPL_H_ 6 #define CONTENT_BROWSER_WEB_CONTENTS_INTERSTITIAL_PAGE_IMPL_H_ 7 8 #include "base/compiler_specific.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/weak_ptr.h" 11 #include "content/browser/renderer_host/render_view_host_delegate.h" 12 #include "content/browser/renderer_host/render_widget_host_delegate.h" 13 #include "content/public/browser/interstitial_page.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 #include "content/public/browser/web_contents_observer.h" 17 #include "content/public/common/renderer_preferences.h" 18 #include "url/gurl.h" 19 20 namespace content { 21 class NavigationEntry; 22 class RenderViewHostImpl; 23 class RenderWidgetHostView; 24 class WebContentsView; 25 class WebContentsImpl; 26 27 enum ResourceRequestAction { 28 BLOCK, 29 RESUME, 30 CANCEL 31 }; 32 33 class CONTENT_EXPORT InterstitialPageImpl 34 : public NON_EXPORTED_BASE(InterstitialPage), 35 public NotificationObserver, 36 public WebContentsObserver, 37 public RenderViewHostDelegate, 38 public RenderWidgetHostDelegate { 39 public: 40 // The different state of actions the user can take in an interstitial. 41 enum ActionState { 42 NO_ACTION, // No action has been taken yet. 43 PROCEED_ACTION, // "Proceed" was selected. 44 DONT_PROCEED_ACTION // "Don't proceed" was selected. 45 }; 46 47 InterstitialPageImpl(WebContents* web_contents, 48 bool new_navigation, 49 const GURL& url, 50 InterstitialPageDelegate* delegate); 51 virtual ~InterstitialPageImpl(); 52 53 // InterstitialPage implementation: 54 virtual void Show() OVERRIDE; 55 virtual void Hide() OVERRIDE; 56 virtual void DontProceed() OVERRIDE; 57 virtual void Proceed() OVERRIDE; 58 virtual RenderViewHost* GetRenderViewHostForTesting() const OVERRIDE; 59 virtual InterstitialPageDelegate* GetDelegateForTesting() OVERRIDE; 60 virtual void DontCreateViewForTesting() OVERRIDE; 61 virtual void SetSize(const gfx::Size& size) OVERRIDE; 62 virtual void Focus() OVERRIDE; 63 64 // Allows the user to navigate away by disabling the interstitial, canceling 65 // the pending request, and unblocking the hidden renderer. The interstitial 66 // will stay visible until the navigation completes. 67 void CancelForNavigation(); 68 69 // Focus the first (last if reverse is true) element in the interstitial page. 70 // Called when tab traversing. 71 void FocusThroughTabTraversal(bool reverse); 72 73 RenderWidgetHostView* GetView(); 74 75 // See description above field. 76 void set_reload_on_dont_proceed(bool value) { 77 reload_on_dont_proceed_ = value; 78 } 79 bool reload_on_dont_proceed() const { return reload_on_dont_proceed_; } 80 81 #if defined(OS_ANDROID) 82 // Android shares a single platform window for all tabs, so we need to expose 83 // the RenderViewHost to properly route gestures to the interstitial. 84 RenderViewHost* GetRenderViewHost() const; 85 #endif 86 87 protected: 88 // NotificationObserver method: 89 virtual void Observe(int type, 90 const NotificationSource& source, 91 const NotificationDetails& details) OVERRIDE; 92 93 // WebContentsObserver implementation: 94 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; 95 virtual void NavigationEntryCommitted( 96 const LoadCommittedDetails& load_details) OVERRIDE; 97 98 // RenderViewHostDelegate implementation: 99 virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE; 100 virtual const GURL& GetURL() const OVERRIDE; 101 virtual void RenderViewTerminated(RenderViewHost* render_view_host, 102 base::TerminationStatus status, 103 int error_code) OVERRIDE; 104 virtual void DidNavigate( 105 RenderViewHost* render_view_host, 106 const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; 107 virtual void UpdateTitle(RenderViewHost* render_view_host, 108 int32 page_id, 109 const string16& title, 110 base::i18n::TextDirection title_direction) OVERRIDE; 111 virtual RendererPreferences GetRendererPrefs( 112 BrowserContext* browser_context) const OVERRIDE; 113 virtual WebPreferences GetWebkitPrefs() OVERRIDE; 114 virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE; 115 virtual void CreateNewWindow( 116 int route_id, 117 int main_frame_route_id, 118 const ViewHostMsg_CreateWindow_Params& params, 119 SessionStorageNamespace* session_storage_namespace) OVERRIDE; 120 virtual void CreateNewWidget(int route_id, 121 WebKit::WebPopupType popup_type) OVERRIDE; 122 virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE; 123 virtual void ShowCreatedWindow(int route_id, 124 WindowOpenDisposition disposition, 125 const gfx::Rect& initial_pos, 126 bool user_gesture) OVERRIDE; 127 virtual void ShowCreatedWidget(int route_id, 128 const gfx::Rect& initial_pos) OVERRIDE; 129 virtual void ShowCreatedFullscreenWidget(int route_id) OVERRIDE; 130 131 virtual SessionStorageNamespace* GetSessionStorageNamespace( 132 SiteInstance* instance) OVERRIDE; 133 134 // RenderWidgetHostDelegate implementation: 135 virtual void RenderWidgetDeleted( 136 RenderWidgetHostImpl* render_widget_host) OVERRIDE; 137 virtual bool PreHandleKeyboardEvent( 138 const NativeWebKeyboardEvent& event, 139 bool* is_keyboard_shortcut) OVERRIDE; 140 virtual void HandleKeyboardEvent( 141 const NativeWebKeyboardEvent& event) OVERRIDE; 142 #if defined(OS_WIN) && defined(USE_AURA) 143 virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE; 144 #endif 145 146 bool enabled() const { return enabled_; } 147 WebContents* web_contents() const; 148 const GURL& url() const { return url_; } 149 150 // Creates the RenderViewHost containing the interstitial content. 151 // Overriden in unit tests. 152 virtual RenderViewHost* CreateRenderViewHost(); 153 154 // Creates the WebContentsView that shows the interstitial RVH. 155 // Overriden in unit tests. 156 virtual WebContentsView* CreateWebContentsView(); 157 158 // Notification magic. 159 NotificationRegistrar notification_registrar_; 160 161 private: 162 class InterstitialPageRVHDelegateView; 163 164 // Disable the interstitial: 165 // - if it is not yet showing, then it won't be shown. 166 // - any command sent by the RenderViewHost will be ignored. 167 void Disable(); 168 169 // Shutdown the RVH. We will be deleted by the time this method returns. 170 void Shutdown(RenderViewHostImpl* render_view_host); 171 172 void OnNavigatingAwayOrTabClosing(); 173 174 // Executes the passed action on the ResourceDispatcher (on the IO thread). 175 // Used to block/resume/cancel requests for the RenderViewHost hidden by this 176 // interstitial. 177 void TakeActionOnResourceDispatcher(ResourceRequestAction action); 178 179 // The contents in which we are displayed. This is valid until Hide is 180 // called, at which point it will be set to NULL because the WebContents 181 // itself may be deleted. 182 WebContentsImpl* web_contents_; 183 184 // The URL that is shown when the interstitial is showing. 185 GURL url_; 186 187 // Whether this interstitial is shown as a result of a new navigation (in 188 // which case a transient navigation entry is created). 189 bool new_navigation_; 190 191 // Whether we should discard the pending navigation entry when not proceeding. 192 // This is to deal with cases where |new_navigation_| is true but a new 193 // pending entry was created since this interstitial was shown and we should 194 // not discard it. 195 bool should_discard_pending_nav_entry_; 196 197 // If true and the user chooses not to proceed the target NavigationController 198 // is reloaded. This is used when two NavigationControllers are merged 199 // (CopyStateFromAndPrune). 200 // The default is false. 201 bool reload_on_dont_proceed_; 202 203 // Whether this interstitial is enabled. See Disable() for more info. 204 bool enabled_; 205 206 // Whether the Proceed or DontProceed methods have been called yet. 207 ActionState action_taken_; 208 209 // The RenderViewHost displaying the interstitial contents. This is valid 210 // until Hide is called, at which point it will be set to NULL, signifying 211 // that shutdown has started. 212 RenderViewHostImpl* render_view_host_; 213 214 // The IDs for the Render[View|Process]Host hidden by this interstitial. 215 int original_child_id_; 216 int original_rvh_id_; 217 218 // Whether or not we should change the title of the contents when hidden (to 219 // revert it to its original value). 220 bool should_revert_web_contents_title_; 221 222 // Whether or not the contents was loading resources when the interstitial was 223 // shown. We restore this state if the user proceeds from the interstitial. 224 bool web_contents_was_loading_; 225 226 // Whether the ResourceDispatcherHost has been notified to cancel/resume the 227 // resource requests blocked for the RenderViewHost. 228 bool resource_dispatcher_host_notified_; 229 230 // The original title of the contents that should be reverted to when the 231 // interstitial is hidden. 232 string16 original_web_contents_title_; 233 234 // Our RenderViewHostViewDelegate, necessary for accelerators to work. 235 scoped_ptr<InterstitialPageRVHDelegateView> rvh_delegate_view_; 236 237 // Settings passed to the renderer. 238 mutable RendererPreferences renderer_preferences_; 239 240 bool create_view_; 241 242 scoped_ptr<InterstitialPageDelegate> delegate_; 243 244 base::WeakPtrFactory<InterstitialPageImpl> weak_ptr_factory_; 245 246 scoped_refptr<SessionStorageNamespace> session_storage_namespace_; 247 248 DISALLOW_COPY_AND_ASSIGN(InterstitialPageImpl); 249 }; 250 251 } // namespace content 252 253 #endif // CONTENT_BROWSER_WEB_CONTENTS_INTERSTITIAL_PAGE_IMPL_H_ 254