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