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_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_ 6 #define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_ 7 8 #include "base/process/kill.h" 9 #include "base/process/process_handle.h" 10 #include "content/common/content_export.h" 11 #include "content/public/browser/navigation_controller.h" 12 #include "content/public/common/page_transition_types.h" 13 #include "ipc/ipc_listener.h" 14 #include "ipc/ipc_sender.h" 15 #include "ui/base/window_open_disposition.h" 16 17 namespace content { 18 19 class NavigationEntry; 20 class RenderFrameHost; 21 class RenderViewHost; 22 class WebContents; 23 class WebContentsImpl; 24 struct FaviconURL; 25 struct FrameNavigateParams; 26 struct LoadCommittedDetails; 27 struct LoadFromMemoryCacheDetails; 28 struct Referrer; 29 struct ResourceRedirectDetails; 30 struct ResourceRequestDetails; 31 32 // An observer API implemented by classes which are interested in various page 33 // load events from WebContents. They also get a chance to filter IPC messages. 34 // 35 // Since a WebContents can be a delegate to almost arbitrarily many 36 // RenderViewHosts, it is important to check in those WebContentsObserver 37 // methods which take a RenderViewHost that the event came from the 38 // RenderViewHost the observer cares about. 39 // 40 // Usually, observers should only care about the current RenderViewHost as 41 // returned by GetRenderViewHost(). 42 // 43 // TODO(creis, jochen): Hide the fact that there are several RenderViewHosts 44 // from the WebContentsObserver API. http://crbug.com/173325 45 class CONTENT_EXPORT WebContentsObserver : public IPC::Listener, 46 public IPC::Sender { 47 public: 48 // Called when a RenderFrameHost associated with this WebContents is created. 49 virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) {} 50 51 // Called whenever a RenderFrameHost associated with this WebContents is 52 // deleted. 53 virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) {} 54 55 // Only one of the two methods below will be called when a RVH is created for 56 // a WebContents, depending on whether it's for an interstitial or not. 57 virtual void RenderViewCreated(RenderViewHost* render_view_host) {} 58 virtual void RenderViewForInterstitialPageCreated( 59 RenderViewHost* render_view_host) {} 60 61 // This method is invoked when the RenderView of the current RenderViewHost 62 // is ready, e.g. because we recreated it after a crash. 63 virtual void RenderViewReady() {} 64 65 // This method is invoked when a RenderViewHost of the WebContents is 66 // deleted. Note that this does not always happen when the WebContents starts 67 // to use a different RenderViewHost, as the old RenderViewHost might get 68 // just swapped out. 69 virtual void RenderViewDeleted(RenderViewHost* render_view_host) {} 70 71 // This method is invoked when the process for the current RenderView crashes. 72 // The WebContents continues to use the RenderViewHost, e.g. when the user 73 // reloads the current page. 74 // When the RenderViewHost is deleted, the RenderViewDeleted method will be 75 // invoked. 76 virtual void RenderProcessGone(base::TerminationStatus status) {} 77 78 // This method is invoked when a WebContents swaps its render view host with 79 // another one, possibly changing processes. The RenderViewHost that has 80 // been replaced is in |old_render_view_host|, which is NULL if the old RVH 81 // was shut down. 82 virtual void RenderViewHostChanged(RenderViewHost* old_host, 83 RenderViewHost* new_host) {} 84 85 // This method is invoked after the WebContents decided which RenderViewHost 86 // to use for the next navigation, but before the navigation starts. 87 virtual void AboutToNavigateRenderView( 88 RenderViewHost* render_view_host) {} 89 90 // This method is invoked after the browser process starts a navigation to a 91 // pending NavigationEntry. It is not called for renderer-initiated 92 // navigations unless they are sent to the browser process via OpenURL. It may 93 // be called multiple times for a given navigation, such as a typed URL 94 // followed by a cross-process client or server redirect. 95 virtual void DidStartNavigationToPendingEntry( 96 const GURL& url, 97 NavigationController::ReloadType reload_type) {} 98 99 // |render_view_host| is the RenderViewHost for which the provisional load is 100 // happening. |frame_id| is a positive, non-zero integer identifying the 101 // navigating frame in the given |render_view_host|. |parent_frame_id| is the 102 // frame identifier of the frame containing the navigating frame, or -1 if the 103 // frame is not contained in another frame. 104 // 105 // Since the URL validation will strip error URLs, or srcdoc URLs, the boolean 106 // flags |is_error_page| and |is_iframe_srcdoc| will indicate that the not 107 // validated URL was either an error page or an iframe srcdoc. 108 // 109 // Note that during a cross-process navigation, several provisional loads 110 // can be on-going in parallel. 111 virtual void DidStartProvisionalLoadForFrame( 112 int64 frame_id, 113 int64 parent_frame_id, 114 bool is_main_frame, 115 const GURL& validated_url, 116 bool is_error_page, 117 bool is_iframe_srcdoc, 118 RenderViewHost* render_view_host) {} 119 120 // This method is invoked right after the DidStartProvisionalLoadForFrame if 121 // the provisional load affects the main frame, or if the provisional load 122 // was redirected. The latter use case is DEPRECATED. You should listen to 123 // WebContentsObserver::DidGetRedirectForResourceRequest instead. 124 virtual void ProvisionalChangeToMainFrameUrl( 125 const GURL& url, 126 RenderViewHost* render_view_host) {} 127 128 // This method is invoked when the provisional load was successfully 129 // committed. The |render_view_host| is now the current RenderViewHost of the 130 // WebContents. 131 // 132 // If the navigation only changed the reference fragment, or was triggered 133 // using the history API (e.g. window.history.replaceState), we will receive 134 // this signal without a prior DidStartProvisionalLoadForFrame signal. 135 virtual void DidCommitProvisionalLoadForFrame( 136 int64 frame_id, 137 const base::string16& frame_unique_name, 138 bool is_main_frame, 139 const GURL& url, 140 PageTransition transition_type, 141 RenderViewHost* render_view_host) {} 142 143 // This method is invoked when the provisional load failed. 144 virtual void DidFailProvisionalLoad(int64 frame_id, 145 const base::string16& frame_unique_name, 146 bool is_main_frame, 147 const GURL& validated_url, 148 int error_code, 149 const base::string16& error_description, 150 RenderViewHost* render_view_host) {} 151 152 // If the provisional load corresponded to the main frame, this method is 153 // invoked in addition to DidCommitProvisionalLoadForFrame. 154 virtual void DidNavigateMainFrame( 155 const LoadCommittedDetails& details, 156 const FrameNavigateParams& params) {} 157 158 // And regardless of what frame navigated, this method is invoked after 159 // DidCommitProvisionalLoadForFrame was invoked. 160 virtual void DidNavigateAnyFrame( 161 const LoadCommittedDetails& details, 162 const FrameNavigateParams& params) {} 163 164 // This method is invoked once the window.document object of the main frame 165 // was created. 166 virtual void DocumentAvailableInMainFrame() {} 167 168 // This method is invoked once the onload handler of the main frame has 169 // completed. 170 virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) {} 171 172 // This method is invoked when the document in the given frame finished 173 // loading. At this point, scripts marked as defer were executed, and 174 // content scripts marked "document_end" get injected into the frame. 175 virtual void DocumentLoadedInFrame(int64 frame_id, 176 RenderViewHost* render_view_host) {} 177 178 // This method is invoked when the navigation is done, i.e. the spinner of 179 // the tab will stop spinning, and the onload event was dispatched. 180 // 181 // If the WebContents is displaying replacement content, e.g. network error 182 // pages, DidFinishLoad is invoked for frames that were not sending 183 // navigational events before. It is safe to ignore these events. 184 virtual void DidFinishLoad(int64 frame_id, 185 const GURL& validated_url, 186 bool is_main_frame, 187 RenderViewHost* render_view_host) {} 188 189 // This method is like DidFinishLoad, but when the load failed or was 190 // cancelled, e.g. window.stop() is invoked. 191 virtual void DidFailLoad(int64 frame_id, 192 const GURL& validated_url, 193 bool is_main_frame, 194 int error_code, 195 const base::string16& error_description, 196 RenderViewHost* render_view_host) {} 197 198 // This method is invoked when content was loaded from an in-memory cache. 199 virtual void DidLoadResourceFromMemoryCache( 200 const LoadFromMemoryCacheDetails& details) {} 201 202 // This method is invoked when a response has been received for a resource 203 // request. 204 virtual void DidGetResourceResponseStart( 205 const ResourceRequestDetails& details) {} 206 207 // This method is invoked when a redirect was received while requesting a 208 // resource. 209 virtual void DidGetRedirectForResourceRequest( 210 const ResourceRedirectDetails& details) {} 211 212 // This method is invoked when a new non-pending navigation entry is created. 213 // This corresponds to one NavigationController entry being created 214 // (in the case of new navigations) or renavigated to (for back/forward 215 // navigations). 216 virtual void NavigationEntryCommitted( 217 const LoadCommittedDetails& load_details) {} 218 219 // This method is invoked when a new WebContents was created in response to 220 // an action in the observed WebContents, e.g. a link with target=_blank was 221 // clicked. The |source_frame_id| indicates in which frame the action took 222 // place. 223 virtual void DidOpenRequestedURL(WebContents* new_contents, 224 const GURL& url, 225 const Referrer& referrer, 226 WindowOpenDisposition disposition, 227 PageTransition transition, 228 int64 source_frame_id) {} 229 230 virtual void FrameDetached(RenderViewHost* render_view_host, 231 int64 frame_id) {} 232 233 // This method is invoked when the renderer has completed its first paint 234 // after a non-empty layout. 235 virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) {} 236 237 // These two methods correspond to the points in time when the spinner of the 238 // tab starts and stops spinning. 239 virtual void DidStartLoading(RenderViewHost* render_view_host) {} 240 virtual void DidStopLoading(RenderViewHost* render_view_host) {} 241 242 // When WebContents::Stop() is called, the WebContents stops loading and then 243 // invokes this method. If there are ongoing navigations, their respective 244 // failure methods will also be invoked. 245 virtual void NavigationStopped() {} 246 247 // This indicates that the next navigation was triggered by a user gesture. 248 virtual void DidGetUserGesture() {} 249 250 // This method is invoked when a RenderViewHost of this WebContents was 251 // configured to ignore UI events, and an UI event took place. 252 virtual void DidGetIgnoredUIEvent() {} 253 254 // These methods are invoked every time the WebContents changes visibility. 255 virtual void WasShown() {} 256 virtual void WasHidden() {} 257 258 // This methods is invoked when the title of the WebContents is set. If the 259 // title was explicitly set, |explicit_set| is true, otherwise the title was 260 // synthesized and |explicit_set| is false. 261 virtual void TitleWasSet(NavigationEntry* entry, bool explicit_set) {} 262 263 virtual void AppCacheAccessed(const GURL& manifest_url, 264 bool blocked_by_policy) {} 265 266 // Notification that a plugin has crashed. 267 // |plugin_pid| is the process ID identifying the plugin process. Note that 268 // this ID is supplied by the renderer, so should not be trusted. Besides, the 269 // corresponding process has probably died at this point. The ID may even have 270 // been reused by a new process. 271 virtual void PluginCrashed(const base::FilePath& plugin_path, 272 base::ProcessId plugin_pid) {} 273 274 // Notification that the given plugin has hung or become unhung. This 275 // notification is only for Pepper plugins. 276 // 277 // The plugin_child_id is the unique child process ID from the plugin. Note 278 // that this ID is supplied by the renderer, so should be validated before 279 // it's used for anything in case there's an exploited renderer. 280 virtual void PluginHungStatusChanged(int plugin_child_id, 281 const base::FilePath& plugin_path, 282 bool is_hung) {} 283 284 // Invoked when WebContents::Clone() was used to clone a WebContents. 285 virtual void DidCloneToNewWebContents(WebContents* old_web_contents, 286 WebContents* new_web_contents) {} 287 288 // Invoked when the WebContents is being destroyed. Gives subclasses a chance 289 // to cleanup. At the time this is invoked |web_contents()| returns NULL. 290 // It is safe to delete 'this' from here. 291 virtual void WebContentsDestroyed(WebContents* web_contents) {} 292 293 // Called when the user agent override for a WebContents has been changed. 294 virtual void UserAgentOverrideSet(const std::string& user_agent) {} 295 296 // Invoked when new FaviconURL candidates are received from the renderer. 297 virtual void DidUpdateFaviconURL(int32 page_id, 298 const std::vector<FaviconURL>& candidates) {} 299 300 // Invoked when a pepper plugin creates and shows or destroys a fullscreen 301 // render widget. 302 virtual void DidShowFullscreenWidget(int routing_id) {} 303 virtual void DidDestroyFullscreenWidget(int routing_id) {} 304 305 // Invoked when visible SSL state (as defined by SSLStatus) changes. 306 virtual void DidChangeVisibleSSLState() {} 307 308 // Invoked when an interstitial page is attached or detached. 309 virtual void DidAttachInterstitialPage() {} 310 virtual void DidDetachInterstitialPage() {} 311 312 // Invoked before a form repost warning is shown. 313 virtual void BeforeFormRepostWarningShow() {} 314 315 // Invoked when the beforeunload handler fires. The time is from the renderer. 316 virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) {} 317 318 // Invoked when a user cancels a before unload dialog. 319 virtual void BeforeUnloadDialogCancelled() {} 320 321 // IPC::Listener implementation. 322 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 323 324 // IPC::Sender implementation. 325 virtual bool Send(IPC::Message* message) OVERRIDE; 326 int routing_id() const; 327 328 protected: 329 // Use this constructor when the object is tied to a single WebContents for 330 // its entire lifetime. 331 explicit WebContentsObserver(WebContents* web_contents); 332 333 // Use this constructor when the object wants to observe a WebContents for 334 // part of its lifetime. It can then call Observe() to start and stop 335 // observing. 336 WebContentsObserver(); 337 338 virtual ~WebContentsObserver(); 339 340 // Start observing a different WebContents; used with the default constructor. 341 void Observe(WebContents* web_contents); 342 343 WebContents* web_contents() const; 344 345 private: 346 friend class WebContentsImpl; 347 348 // Invoked from WebContentsImpl. Invokes WebContentsDestroyed and NULL out 349 // |web_contents_|. 350 void WebContentsImplDestroyed(); 351 352 WebContentsImpl* web_contents_; 353 354 DISALLOW_COPY_AND_ASSIGN(WebContentsObserver); 355 }; 356 357 } // namespace content 358 359 #endif // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_ 360