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