• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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