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