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.
5 #ifndef CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_
6 #define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_
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/security_style.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/page_transition_types.h"
18 #include "ui/base/window_open_disposition.h"
22 class NavigationEntry
;
23 class RenderFrameHost
;
26 class WebContentsImpl
;
27 struct AXEventNotificationDetails
;
29 struct FrameNavigateParams
;
30 struct LoadCommittedDetails
;
31 struct LoadFromMemoryCacheDetails
;
33 struct ResourceRedirectDetails
;
34 struct ResourceRequestDetails
;
35 struct SecurityStyleExplanations
;
37 // An observer API implemented by classes which are interested in various page
38 // load events from WebContents. They also get a chance to filter IPC messages.
40 // Since a WebContents can be a delegate to almost arbitrarily many
41 // RenderViewHosts, it is important to check in those WebContentsObserver
42 // methods which take a RenderViewHost that the event came from the
43 // RenderViewHost the observer cares about.
45 // Usually, observers should only care about the current RenderViewHost as
46 // returned by GetRenderViewHost().
48 // TODO(creis, jochen): Hide the fact that there are several RenderViewHosts
49 // from the WebContentsObserver API. http://crbug.com/173325
50 class CONTENT_EXPORT WebContentsObserver
: public IPC::Listener
,
53 // Called when a RenderFrame for |render_frame_host| is created in the
54 // renderer process. Use |RenderFrameDeleted| to listen for when this
55 // RenderFrame goes away.
56 virtual void RenderFrameCreated(RenderFrameHost
* render_frame_host
) {}
58 // Called when a RenderFrame for |render_frame_host| is deleted or the
59 // renderer process in which it runs it has died. Use |RenderFrameCreated| to
60 // listen for when RenderFrame objects are created.
61 virtual void RenderFrameDeleted(RenderFrameHost
* render_frame_host
) {}
63 // This method is invoked whenever one of the current frames of a WebContents
64 // swaps its RenderFrameHost with another one; for example because that frame
65 // navigated and the new content is in a different process. The
66 // RenderFrameHost that has been replaced is in |old_host|, which can be
67 // nullptr if the old RenderFrameHost was shut down or a new frame has been
68 // created and no old RenderFrameHost exists.
70 // This method, in combination with |FrameDeleted|, is appropriate for
71 // observers wishing to track the set of current RenderFrameHosts -- i.e.,
72 // those hosts that would be visited by calling WebContents::ForEachFrame.
73 virtual void RenderFrameHostChanged(RenderFrameHost
* old_host
,
74 RenderFrameHost
* new_host
) {}
76 // This method is invoked when a subframe associated with a WebContents is
77 // deleted or the WebContents is destroyed and the top-level frame is deleted.
78 // Use |RenderFrameHostChanged| to listen for when a RenderFrameHost object is
79 // made the current host for a frame.
80 virtual void FrameDeleted(RenderFrameHost
* render_frame_host
) {}
82 // This is called when a RVH is created for a WebContents, but not if it's an
84 virtual void RenderViewCreated(RenderViewHost
* render_view_host
) {}
86 // Called for every RenderFrameHost that's created for an interstitial.
87 virtual void RenderFrameForInterstitialPageCreated(
88 RenderFrameHost
* render_frame_host
) {}
90 // This method is invoked when the RenderView of the current RenderViewHost
91 // is ready, e.g. because we recreated it after a crash.
92 virtual void RenderViewReady() {}
94 // This method is invoked when a RenderViewHost of the WebContents is
95 // deleted. Note that this does not always happen when the WebContents starts
96 // to use a different RenderViewHost, as the old RenderViewHost might get
98 virtual void RenderViewDeleted(RenderViewHost
* render_view_host
) {}
100 // This method is invoked when the process for the current main
101 // RenderFrameHost exits (usually by crashing, though possibly by other
102 // means). The WebContents continues to use the RenderFrameHost, e.g. when the
103 // user reloads the current page. When the RenderFrameHost itself is deleted,
104 // the RenderFrameDeleted method will be invoked.
106 // Note that this is triggered upstream through
107 // RenderProcessHostObserver::RenderProcessExited(); for code that doesn't
108 // otherwise need to be a WebContentsObserver, that API is probably a better
110 virtual void RenderProcessGone(base::TerminationStatus status
) {}
112 // This method is invoked when a WebContents swaps its visible RenderViewHost
113 // with another one, possibly changing processes. The RenderViewHost that has
114 // been replaced is in |old_host|, which is nullptr if the old RVH was shut
116 virtual void RenderViewHostChanged(RenderViewHost
* old_host
,
117 RenderViewHost
* new_host
) {}
119 // This method is invoked after the WebContents decides which RenderFrameHost
120 // to use for the next browser-initiated navigation, but before the navigation
121 // starts. It is not called for most renderer-initiated navigations, and it
122 // does not guarantee that the navigation will commit (e.g., 204s, downloads).
124 // DEPRECATED. This method is difficult to use correctly and should be
125 // removed. TODO(creis): Remove in http://crbug.com/424641.
126 virtual void AboutToNavigateRenderFrame(RenderFrameHost
* old_host
,
127 RenderFrameHost
* new_host
) {}
129 // This method is invoked after the browser process starts a navigation to a
130 // pending NavigationEntry. It is not called for renderer-initiated
131 // navigations unless they are sent to the browser process via OpenURL. It may
132 // be called multiple times for a given navigation, such as a typed URL
133 // followed by a cross-process client or server redirect.
134 virtual void DidStartNavigationToPendingEntry(
136 NavigationController::ReloadType reload_type
) {}
138 // |render_frame_host| is the RenderFrameHost for which the provisional load
141 // Since the URL validation will strip error URLs, or srcdoc URLs, the boolean
142 // flags |is_error_page| and |is_iframe_srcdoc| will indicate that the not
143 // validated URL was either an error page or an iframe srcdoc.
145 // Note that during a cross-process navigation, several provisional loads
146 // can be on-going in parallel.
147 virtual void DidStartProvisionalLoadForFrame(
148 RenderFrameHost
* render_frame_host
,
149 const GURL
& validated_url
,
151 bool is_iframe_srcdoc
) {}
153 // This method is invoked when the provisional load was successfully
156 // If the navigation only changed the reference fragment, or was triggered
157 // using the history API (e.g. window.history.replaceState), we will receive
158 // this signal without a prior DidStartProvisionalLoadForFrame signal.
159 virtual void DidCommitProvisionalLoadForFrame(
160 RenderFrameHost
* render_frame_host
,
162 ui::PageTransition transition_type
) {}
164 // This method is invoked when the provisional load failed.
165 virtual void DidFailProvisionalLoad(
166 RenderFrameHost
* render_frame_host
,
167 const GURL
& validated_url
,
169 const base::string16
& error_description
,
170 bool was_ignored_by_handler
) {}
172 // If the provisional load corresponded to the main frame, this method is
173 // invoked in addition to DidCommitProvisionalLoadForFrame.
174 virtual void DidNavigateMainFrame(
175 const LoadCommittedDetails
& details
,
176 const FrameNavigateParams
& params
) {}
178 // And regardless of what frame navigated, this method is invoked after
179 // DidCommitProvisionalLoadForFrame was invoked.
180 virtual void DidNavigateAnyFrame(
181 RenderFrameHost
* render_frame_host
,
182 const LoadCommittedDetails
& details
,
183 const FrameNavigateParams
& params
) {}
185 // This method is invoked when the SecurityStyle of the WebContents changes.
186 // |security_style| is the new SecurityStyle. |security_style_explanations|
187 // contains human-readable strings explaining why the SecurityStyle of the
188 // page has been downgraded.
189 virtual void SecurityStyleChanged(
190 SecurityStyle security_style
,
191 const SecurityStyleExplanations
& security_style_explanations
) {}
193 // This method is invoked once the window.document object of the main frame
195 virtual void DocumentAvailableInMainFrame() {}
197 // This method is invoked once the onload handler of the main frame has
199 virtual void DocumentOnLoadCompletedInMainFrame() {}
201 // This method is invoked when the document in the given frame finished
202 // loading. At this point, scripts marked as defer were executed, and
203 // content scripts marked "document_end" get injected into the frame.
204 virtual void DocumentLoadedInFrame(RenderFrameHost
* render_frame_host
) {}
206 // This method is invoked when the navigation is done, i.e. the spinner of
207 // the tab will stop spinning, and the onload event was dispatched.
209 // If the WebContents is displaying replacement content, e.g. network error
210 // pages, DidFinishLoad is invoked for frames that were not sending
211 // navigational events before. It is safe to ignore these events.
212 virtual void DidFinishLoad(RenderFrameHost
* render_frame_host
,
213 const GURL
& validated_url
) {}
215 // This method is like DidFinishLoad, but when the load failed or was
216 // cancelled, e.g. window.stop() is invoked.
217 virtual void DidFailLoad(RenderFrameHost
* render_frame_host
,
218 const GURL
& validated_url
,
220 const base::string16
& error_description
,
221 bool was_ignored_by_handler
) {}
223 // This method is invoked when content was loaded from an in-memory cache.
224 virtual void DidLoadResourceFromMemoryCache(
225 const LoadFromMemoryCacheDetails
& details
) {}
227 // This method is invoked when a response has been received for a resource
229 virtual void DidGetResourceResponseStart(
230 const ResourceRequestDetails
& details
) {}
232 // This method is invoked when a redirect was received while requesting a
234 virtual void DidGetRedirectForResourceRequest(
235 RenderFrameHost
* render_frame_host
,
236 const ResourceRedirectDetails
& details
) {}
238 // This method is invoked when a new non-pending navigation entry is created.
239 // This corresponds to one NavigationController entry being created
240 // (in the case of new navigations) or renavigated to (for back/forward
242 virtual void NavigationEntryCommitted(
243 const LoadCommittedDetails
& load_details
) {}
245 // This method is invoked when a new WebContents was created in response to
246 // an action in the observed WebContents, e.g. a link with target=_blank was
247 // clicked. The |source_render_frame_host| is the frame in which the action
249 virtual void DidOpenRequestedURL(WebContents
* new_contents
,
250 RenderFrameHost
* source_render_frame_host
,
252 const Referrer
& referrer
,
253 WindowOpenDisposition disposition
,
254 ui::PageTransition transition
) {}
256 // This method is invoked when the renderer process has completed its first
257 // paint after a non-empty layout.
258 virtual void DidFirstVisuallyNonEmptyPaint() {}
260 // These two methods correspond to the points in time when the spinner of the
261 // tab starts and stops spinning.
262 virtual void DidStartLoading() {}
263 virtual void DidStopLoading() {}
265 // When WebContents::Stop() is called, the WebContents stops loading and then
266 // invokes this method. If there are ongoing navigations, their respective
267 // failure methods will also be invoked.
268 virtual void NavigationStopped() {}
270 // This indicates that the next navigation was triggered by a user gesture.
271 virtual void DidGetUserGesture() {}
273 // This method is invoked when a RenderViewHost of this WebContents was
274 // configured to ignore UI events, and an UI event took place.
275 virtual void DidGetIgnoredUIEvent() {}
277 // These methods are invoked every time the WebContents changes visibility.
278 virtual void WasShown() {}
279 virtual void WasHidden() {}
281 // Invoked when the main frame changes size.
282 virtual void MainFrameWasResized(bool width_changed
) {}
284 // Invoked when the given frame changes its window.name property.
285 virtual void FrameNameChanged(RenderFrameHost
* render_frame_host
,
286 const std::string
& name
) {}
288 // This methods is invoked when the title of the WebContents is set. If the
289 // title was explicitly set, |explicit_set| is true, otherwise the title was
290 // synthesized and |explicit_set| is false.
291 virtual void TitleWasSet(NavigationEntry
* entry
, bool explicit_set
) {}
293 virtual void AppCacheAccessed(const GURL
& manifest_url
,
294 bool blocked_by_policy
) {}
296 // These methods are invoked when a Pepper plugin instance is created/deleted
298 virtual void PepperInstanceCreated() {}
299 virtual void PepperInstanceDeleted() {}
301 // Notification that a plugin has crashed.
302 // |plugin_pid| is the process ID identifying the plugin process. Note that
303 // this ID is supplied by the renderer process, so should not be trusted.
304 // Besides, the corresponding process has probably died at this point. The ID
305 // may even have been reused by a new process.
306 virtual void PluginCrashed(const base::FilePath
& plugin_path
,
307 base::ProcessId plugin_pid
) {}
309 // Notification that the given plugin has hung or become unhung. This
310 // notification is only for Pepper plugins.
312 // The plugin_child_id is the unique child process ID from the plugin. Note
313 // that this ID is supplied by the renderer process, so should be validated
314 // before it's used for anything in case there's an exploited renderer
316 virtual void PluginHungStatusChanged(int plugin_child_id
,
317 const base::FilePath
& plugin_path
,
320 // Invoked when WebContents::Clone() was used to clone a WebContents.
321 virtual void DidCloneToNewWebContents(WebContents
* old_web_contents
,
322 WebContents
* new_web_contents
) {}
324 // Invoked when the WebContents is being destroyed. Gives subclasses a chance
325 // to cleanup. After the whole loop over all WebContentsObservers has been
326 // finished, web_contents() returns nullptr.
327 virtual void WebContentsDestroyed() {}
329 // Called when the user agent override for a WebContents has been changed.
330 virtual void UserAgentOverrideSet(const std::string
& user_agent
) {}
332 // Invoked when new FaviconURL candidates are received from the renderer
334 virtual void DidUpdateFaviconURL(const std::vector
<FaviconURL
>& candidates
) {}
336 // Invoked when a pepper plugin creates and shows or destroys a fullscreen
338 virtual void DidShowFullscreenWidget(int routing_id
) {}
339 virtual void DidDestroyFullscreenWidget(int routing_id
) {}
341 // Invoked when the renderer process has toggled the tab into/out of
343 virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen
) {}
345 // Invoked when an interstitial page is attached or detached.
346 virtual void DidAttachInterstitialPage() {}
347 virtual void DidDetachInterstitialPage() {}
349 // Invoked before a form repost warning is shown.
350 virtual void BeforeFormRepostWarningShow() {}
352 // Invoked when the beforeunload handler fires. The time is from the renderer
354 virtual void BeforeUnloadFired(const base::TimeTicks
& proceed_time
) {}
356 // Invoked when a user cancels a before unload dialog.
357 virtual void BeforeUnloadDialogCancelled() {}
359 // Invoked when an accessibility event is received from the renderer process.
360 virtual void AccessibilityEventReceived(
361 const std::vector
<AXEventNotificationDetails
>& details
) {}
363 // Invoked when theme color is changed to |theme_color|.
364 virtual void DidChangeThemeColor(SkColor theme_color
) {}
366 // Invoked when media is playing.
367 virtual void MediaStartedPlaying() {}
369 // Invoked when media is paused.
370 virtual void MediaPaused() {}
372 // Invoked when media session has changed its state.
373 virtual void MediaSessionStateChanged(bool is_controllable
,
374 bool is_suspended
) {}
376 // Invoked if an IPC message is coming from a specific RenderFrameHost.
377 virtual bool OnMessageReceived(const IPC::Message
& message
,
378 RenderFrameHost
* render_frame_host
);
380 // Notification that |contents| has gained focus.
381 virtual void OnWebContentsFocused() {}
383 // IPC::Listener implementation.
384 bool OnMessageReceived(const IPC::Message
& message
) override
;
386 // IPC::Sender implementation.
387 bool Send(IPC::Message
* message
) override
;
388 int routing_id() const;
390 WebContents
* web_contents() const;
393 // Use this constructor when the object is tied to a single WebContents for
394 // its entire lifetime.
395 explicit WebContentsObserver(WebContents
* web_contents
);
397 // Use this constructor when the object wants to observe a WebContents for
398 // part of its lifetime. It can then call Observe() to start and stop
400 WebContentsObserver();
402 ~WebContentsObserver() override
;
404 // Start observing a different WebContents; used with the default constructor.
405 void Observe(WebContents
* web_contents
);
408 friend class WebContentsImpl
;
410 void ResetWebContents();
412 WebContentsImpl
* web_contents_
;
414 DISALLOW_COPY_AND_ASSIGN(WebContentsObserver
);
417 } // namespace content
419 #endif // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_