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