web_contents_observer.h revision 116680a4aac90f2aa7413d9095a592090648e557
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
19namespace content {
20
21class NavigationEntry;
22class RenderFrameHost;
23class RenderViewHost;
24class WebContents;
25class WebContentsImpl;
26struct AXEventNotificationDetails;
27struct FaviconURL;
28struct FrameNavigateParams;
29struct LoadCommittedDetails;
30struct LoadFromMemoryCacheDetails;
31struct Referrer;
32struct ResourceRedirectDetails;
33struct 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
48class CONTENT_EXPORT WebContentsObserver : public IPC::Listener,
49                                           public IPC::Sender {
50 public:
51  // Called when a RenderFrameHost associated with this WebContents is created.
52  virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) {}
53
54  // Called whenever a RenderFrameHost associated with this WebContents is
55  // deleted.
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.
60  virtual void RenderViewCreated(RenderViewHost* render_view_host) {}
61
62  // Called for every RenderFrameHost that's created for an interstitial.
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.
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.
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().
83  virtual void RenderProcessGone(base::TerminationStatus status) {}
84
85  // This method is invoked when a WebContents swaps its visible RenderViewHost
86  // with another one, possibly changing processes. The RenderViewHost that has
87  // been replaced is in |old_host|, which is NULL if the old RVH was shut down.
88  virtual void RenderViewHostChanged(RenderViewHost* old_host,
89                                     RenderViewHost* new_host) {}
90
91  // This method is invoked whenever one of the current frames of a WebContents
92  // swaps its RenderFrameHost with another one; for example because that frame
93  // navigated and the new content is in a different process. The
94  // RenderFrameHost that has been replaced is in |old_host|, which can be NULL
95  // if the old RFH was shut down.
96  //
97  // This method, in combination with RenderFrameDeleted, is appropriate for
98  // observers wishing to track the set of active RenderFrameHosts -- i.e.,
99  // those hosts that would be visited by calling WebContents::ForEachFrame.
100  virtual void RenderFrameHostChanged(RenderFrameHost* old_host,
101                                      RenderFrameHost* new_host) {}
102
103  // This method is invoked after the WebContents decided which RenderViewHost
104  // to use for the next navigation, but before the navigation starts.
105  virtual void AboutToNavigateRenderView(
106      RenderViewHost* render_view_host) {}
107
108  // This method is invoked after the browser process starts a navigation to a
109  // pending NavigationEntry. It is not called for renderer-initiated
110  // navigations unless they are sent to the browser process via OpenURL. It may
111  // be called multiple times for a given navigation, such as a typed URL
112  // followed by a cross-process client or server redirect.
113  virtual void DidStartNavigationToPendingEntry(
114      const GURL& url,
115      NavigationController::ReloadType reload_type) {}
116
117  // |render_frame_host| is the RenderFrameHost for which the provisional load
118  // is happening.
119  //
120  // Since the URL validation will strip error URLs, or srcdoc URLs, the boolean
121  // flags |is_error_page| and |is_iframe_srcdoc| will indicate that the not
122  // validated URL was either an error page or an iframe srcdoc.
123  //
124  // Note that during a cross-process navigation, several provisional loads
125  // can be on-going in parallel.
126  virtual void DidStartProvisionalLoadForFrame(
127      RenderFrameHost* render_frame_host,
128      const GURL& validated_url,
129      bool is_error_page,
130      bool is_iframe_srcdoc) {}
131
132  // This method is invoked right after the DidStartProvisionalLoadForFrame if
133  // the provisional load affects the main frame, or if the provisional load
134  // was redirected. The latter use case is DEPRECATED. You should listen to
135  // WebContentsObserver::DidGetRedirectForResourceRequest instead.
136  virtual void ProvisionalChangeToMainFrameUrl(
137      const GURL& url,
138      RenderFrameHost* render_frame_host) {}
139
140  // This method is invoked when the provisional load was successfully
141  // committed.
142  //
143  // If the navigation only changed the reference fragment, or was triggered
144  // using the history API (e.g. window.history.replaceState), we will receive
145  // this signal without a prior DidStartProvisionalLoadForFrame signal.
146  virtual void DidCommitProvisionalLoadForFrame(
147      RenderFrameHost* render_frame_host,
148      const GURL& url,
149      PageTransition transition_type) {}
150
151  // This method is invoked when the provisional load failed.
152  virtual void DidFailProvisionalLoad(
153      RenderFrameHost* render_frame_host,
154      const GURL& validated_url,
155      int error_code,
156      const base::string16& error_description) {}
157
158  // If the provisional load corresponded to the main frame, this method is
159  // invoked in addition to DidCommitProvisionalLoadForFrame.
160  virtual void DidNavigateMainFrame(
161      const LoadCommittedDetails& details,
162      const FrameNavigateParams& params) {}
163
164  // And regardless of what frame navigated, this method is invoked after
165  // DidCommitProvisionalLoadForFrame was invoked.
166  virtual void DidNavigateAnyFrame(
167      const LoadCommittedDetails& details,
168      const FrameNavigateParams& params) {}
169
170  // This method is invoked once the window.document object of the main frame
171  // was created.
172  virtual void DocumentAvailableInMainFrame() {}
173
174  // This method is invoked once the onload handler of the main frame has
175  // completed.
176  virtual void DocumentOnLoadCompletedInMainFrame() {}
177
178  // This method is invoked when the document in the given frame finished
179  // loading. At this point, scripts marked as defer were executed, and
180  // content scripts marked "document_end" get injected into the frame.
181  virtual void DocumentLoadedInFrame(RenderFrameHost* render_frame_host) {}
182
183  // This method is invoked when the navigation is done, i.e. the spinner of
184  // the tab will stop spinning, and the onload event was dispatched.
185  //
186  // If the WebContents is displaying replacement content, e.g. network error
187  // pages, DidFinishLoad is invoked for frames that were not sending
188  // navigational events before. It is safe to ignore these events.
189  virtual void DidFinishLoad(RenderFrameHost* render_frame_host,
190                             const GURL& validated_url) {}
191
192  // This method is like DidFinishLoad, but when the load failed or was
193  // cancelled, e.g. window.stop() is invoked.
194  virtual void DidFailLoad(RenderFrameHost* render_frame_host,
195                           const GURL& validated_url,
196                           int error_code,
197                           const base::string16& error_description) {}
198
199  // This method is invoked when content was loaded from an in-memory cache.
200  virtual void DidLoadResourceFromMemoryCache(
201      const LoadFromMemoryCacheDetails& details) {}
202
203  // This method is invoked when a response has been received for a resource
204  // request.
205  virtual void DidGetResourceResponseStart(
206      const ResourceRequestDetails& details) {}
207
208  // This method is invoked when a redirect was received while requesting a
209  // resource.
210  virtual void DidGetRedirectForResourceRequest(
211      RenderViewHost* render_view_host,
212      const ResourceRedirectDetails& details) {}
213
214  // This method is invoked when a new non-pending navigation entry is created.
215  // This corresponds to one NavigationController entry being created
216  // (in the case of new navigations) or renavigated to (for back/forward
217  // navigations).
218  virtual void NavigationEntryCommitted(
219      const LoadCommittedDetails& load_details) {}
220
221  // This method is invoked when a new WebContents was created in response to
222  // an action in the observed WebContents, e.g. a link with target=_blank was
223  // clicked. The |source_frame_id| indicates in which frame the action took
224  // place.
225  virtual void DidOpenRequestedURL(WebContents* new_contents,
226                                   const GURL& url,
227                                   const Referrer& referrer,
228                                   WindowOpenDisposition disposition,
229                                   PageTransition transition,
230                                   int64 source_frame_id) {}
231
232  virtual void FrameDetached(RenderFrameHost* render_frame_host) {}
233
234  // This method is invoked when the renderer has completed its first paint
235  // after a non-empty layout.
236  virtual void DidFirstVisuallyNonEmptyPaint() {}
237
238  // These two methods correspond to the points in time when the spinner of the
239  // tab starts and stops spinning.
240  virtual void DidStartLoading(RenderViewHost* render_view_host) {}
241  virtual void DidStopLoading(RenderViewHost* render_view_host) {}
242
243  // When WebContents::Stop() is called, the WebContents stops loading and then
244  // invokes this method. If there are ongoing navigations, their respective
245  // failure methods will also be invoked.
246  virtual void NavigationStopped() {}
247
248  // This indicates that the next navigation was triggered by a user gesture.
249  virtual void DidGetUserGesture() {}
250
251  // This method is invoked when a RenderViewHost of this WebContents was
252  // configured to ignore UI events, and an UI event took place.
253  virtual void DidGetIgnoredUIEvent() {}
254
255  // These methods are invoked every time the WebContents changes visibility.
256  virtual void WasShown() {}
257  virtual void WasHidden() {}
258
259  // This methods is invoked when the title of the WebContents is set. If the
260  // title was explicitly set, |explicit_set| is true, otherwise the title was
261  // synthesized and |explicit_set| is false.
262  virtual void TitleWasSet(NavigationEntry* entry, bool explicit_set) {}
263
264  virtual void AppCacheAccessed(const GURL& manifest_url,
265                                bool blocked_by_policy) {}
266
267  // Notification that a plugin has crashed.
268  // |plugin_pid| is the process ID identifying the plugin process. Note that
269  // this ID is supplied by the renderer, so should not be trusted. Besides, the
270  // corresponding process has probably died at this point. The ID may even have
271  // been reused by a new process.
272  virtual void PluginCrashed(const base::FilePath& plugin_path,
273                             base::ProcessId plugin_pid) {}
274
275  // Notification that the given plugin has hung or become unhung. This
276  // notification is only for Pepper plugins.
277  //
278  // The plugin_child_id is the unique child process ID from the plugin. Note
279  // that this ID is supplied by the renderer, so should be validated before
280  // it's used for anything in case there's an exploited renderer.
281  virtual void PluginHungStatusChanged(int plugin_child_id,
282                                       const base::FilePath& plugin_path,
283                                       bool is_hung) {}
284
285  // Invoked when WebContents::Clone() was used to clone a WebContents.
286  virtual void DidCloneToNewWebContents(WebContents* old_web_contents,
287                                        WebContents* new_web_contents) {}
288
289  // Invoked when the WebContents is being destroyed. Gives subclasses a chance
290  // to cleanup. After the whole loop over all WebContentsObservers has been
291  // finished, web_contents() returns NULL.
292  virtual void WebContentsDestroyed() {}
293
294  // Called when the user agent override for a WebContents has been changed.
295  virtual void UserAgentOverrideSet(const std::string& user_agent) {}
296
297  // Invoked when new FaviconURL candidates are received from the renderer.
298  virtual void DidUpdateFaviconURL(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 the renderer has toggled the tab into/out of fullscreen mode.
306  virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) {}
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  // Invoked when an accessibility event is received from the renderer.
322  virtual void AccessibilityEventReceived(
323      const std::vector<AXEventNotificationDetails>& details) {}
324
325  // Invoked when theme color is changed to |theme_color|.
326  virtual void DidChangeThemeColor(SkColor theme_color) {}
327
328  // Invoked if an IPC message is coming from a specific RenderFrameHost.
329  virtual bool OnMessageReceived(const IPC::Message& message,
330                                 RenderFrameHost* render_frame_host);
331
332  // IPC::Listener implementation.
333  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
334
335  // IPC::Sender implementation.
336  virtual bool Send(IPC::Message* message) OVERRIDE;
337  int routing_id() const;
338
339 protected:
340  // Use this constructor when the object is tied to a single WebContents for
341  // its entire lifetime.
342  explicit WebContentsObserver(WebContents* web_contents);
343
344  // Use this constructor when the object wants to observe a WebContents for
345  // part of its lifetime.  It can then call Observe() to start and stop
346  // observing.
347  WebContentsObserver();
348
349  virtual ~WebContentsObserver();
350
351  // Start observing a different WebContents; used with the default constructor.
352  void Observe(WebContents* web_contents);
353
354  WebContents* web_contents() const;
355
356 private:
357  friend class WebContentsImpl;
358
359  void ResetWebContents();
360
361  WebContentsImpl* web_contents_;
362
363  DISALLOW_COPY_AND_ASSIGN(WebContentsObserver);
364};
365
366}  // namespace content
367
368#endif  // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_
369