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 <stdint.h>
9 
10 #include "base/macros.h"
11 #include "base/optional.h"
12 #include "base/process/kill.h"
13 #include "base/process/process_handle.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "components/viz/common/vertical_scroll_direction.h"
16 #include "content/common/content_export.h"
17 #include "content/public/browser/allow_service_worker_result.h"
18 #include "content/public/browser/cookie_access_details.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/reload_type.h"
21 #include "content/public/browser/visibility.h"
22 #include "ipc/ipc_listener.h"
23 #include "mojo/public/cpp/system/message_pipe.h"
24 #include "services/network/public/mojom/fetch_api.mojom-forward.h"
25 #include "services/service_manager/public/cpp/bind_source_info.h"
26 #include "third_party/blink/public/common/input/web_input_event.h"
27 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
28 #include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
29 #include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
30 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-forward.h"
31 #include "third_party/skia/include/core/SkColor.h"
32 #include "ui/base/page_transition_types.h"
33 #include "ui/base/window_open_disposition.h"
34 
35 namespace blink {
36 namespace mojom {
37 enum class ViewportFit;
38 }  // namespace mojom
39 }  // namespace blink
40 
41 namespace gfx {
42 class Size;
43 }  // namespace gfx
44 
45 namespace content {
46 
47 class NavigationEntry;
48 class NavigationHandle;
49 class RenderFrameHost;
50 class RenderProcessHost;
51 class RenderViewHost;
52 class RenderWidgetHost;
53 class WebContents;
54 class WebContentsImpl;
55 struct AXEventNotificationDetails;
56 struct AXLocationChangeNotificationDetails;
57 struct EntryChangedDetails;
58 struct FocusedNodeDetails;
59 struct LoadCommittedDetails;
60 struct MediaPlayerId;
61 struct PrunedDetails;
62 struct Referrer;
63 
64 // An observer API implemented by classes which are interested in various page
65 // load events from WebContents.  They also get a chance to filter IPC messages.
66 //
67 // Since a WebContents can be a delegate to almost arbitrarily many
68 // RenderViewHosts, it is important to check in those WebContentsObserver
69 // methods which take a RenderViewHost that the event came from the
70 // RenderViewHost the observer cares about.
71 //
72 // Usually, observers should only care about the current RenderViewHost as
73 // returned by GetRenderViewHost().
74 //
75 // TODO(creis, jochen): Hide the fact that there are several RenderViewHosts
76 // from the WebContentsObserver API. http://crbug.com/173325
77 class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
78  public:
79   // Frames and Views ----------------------------------------------------------
80 
81   // Called when a RenderFrame for |render_frame_host| is created in the
82   // renderer process. Use |RenderFrameDeleted| to listen for when this
83   // RenderFrame goes away.
RenderFrameCreated(RenderFrameHost * render_frame_host)84   virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) {}
85 
86   // Called when a RenderFrame for |render_frame_host| is deleted or the
87   // renderer process in which it runs it has died. Use |RenderFrameCreated| to
88   // listen for when RenderFrame objects are created.
RenderFrameDeleted(RenderFrameHost * render_frame_host)89   virtual void RenderFrameDeleted(RenderFrameHost* render_frame_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
95   // nullptr if the old RenderFrameHost was shut down or a new frame has been
96   // created and no old RenderFrameHost exists.
97   //
98   // This method, in combination with |FrameDeleted|, is appropriate for
99   // observers wishing to track the set of current RenderFrameHosts -- i.e.,
100   // those hosts that would be visited by calling WebContents::ForEachFrame().
RenderFrameHostChanged(RenderFrameHost * old_host,RenderFrameHost * new_host)101   virtual void RenderFrameHostChanged(RenderFrameHost* old_host,
102                                       RenderFrameHost* new_host) {}
103 
104   // This method is invoked when a subframe associated with a WebContents is
105   // deleted or the WebContents is destroyed and the top-level frame is deleted.
106   // Use |RenderFrameHostChanged| to listen for when a RenderFrameHost object is
107   // made the current host for a frame.
FrameDeleted(RenderFrameHost * render_frame_host)108   virtual void FrameDeleted(RenderFrameHost* render_frame_host) {}
109 
110   // This is called when a RVH is created for a WebContents, but not if it's an
111   // interstitial.
RenderViewCreated(RenderViewHost * render_view_host)112   virtual void RenderViewCreated(RenderViewHost* render_view_host) {}
113 
114   // This method is invoked when the RenderView of the current RenderViewHost
115   // is ready, e.g. because we recreated it after a crash.
RenderViewReady()116   virtual void RenderViewReady() {}
117 
118   // This method is invoked when a RenderViewHost of the WebContents is
119   // deleted. Note that this does not always happen when the WebContents starts
120   // to use a different RenderViewHost, as the old RenderViewHost might get
121   // just swapped out.
RenderViewDeleted(RenderViewHost * render_view_host)122   virtual void RenderViewDeleted(RenderViewHost* render_view_host) {}
123 
124   // This method is invoked when the process for the current main
125   // RenderFrameHost exits (usually by crashing, though possibly by other
126   // means). The WebContents continues to use the RenderFrameHost, e.g. when the
127   // user reloads the current page. When the RenderFrameHost itself is deleted,
128   // the RenderFrameDeleted method will be invoked.
129   //
130   // Note that this is triggered upstream through
131   // RenderProcessHostObserver::RenderProcessExited(); for code that doesn't
132   // otherwise need to be a WebContentsObserver, that API is probably a better
133   // choice.
RenderProcessGone(base::TerminationStatus status)134   virtual void RenderProcessGone(base::TerminationStatus status) {}
135 
136   // This method is invoked when a WebContents swaps its visible RenderViewHost
137   // with another one, possibly changing processes. The RenderViewHost that has
138   // been replaced is in |old_host|, which is nullptr if the old RVH was shut
139   // down.
RenderViewHostChanged(RenderViewHost * old_host,RenderViewHost * new_host)140   virtual void RenderViewHostChanged(RenderViewHost* old_host,
141                                      RenderViewHost* new_host) {}
142 
143   // This method is invoked when a process in the WebContents becomes
144   // unresponsive.
OnRendererUnresponsive(RenderProcessHost * render_process_host)145   virtual void OnRendererUnresponsive(RenderProcessHost* render_process_host) {}
146 
147   // See WebContentsDelegate::RendererResponsive().
OnRendererResponsive(RenderProcessHost * render_process_host)148   virtual void OnRendererResponsive(RenderProcessHost* render_process_host) {}
149 
150   // Navigation ----------------------------------------------------------------
151 
152   // Called when a navigation started in the WebContents. |navigation_handle|
153   // is unique to a specific navigation. The same |navigation_handle| will be
154   // provided on subsequent calls to DidRedirectNavigation, DidFinishNavigation,
155   // and ReadyToCommitNavigation when related to this navigation. Observers
156   // should clear any references to |navigation_handle| in DidFinishNavigation,
157   // just before it is destroyed.
158   //
159   // Note that this is fired by navigations in any frame of the WebContents,
160   // not just the main frame.
161   //
162   // Note that this is fired by same-document navigations, such as fragment
163   // navigations or pushState/replaceState, which will not result in a document
164   // change. To filter these out, use NavigationHandle::IsSameDocument.
165   //
166   // Note that more than one navigation can be ongoing in the same frame at the
167   // same time (including the main frame). Each will get its own
168   // NavigationHandle.
169   //
170   // Note that there is no guarantee that DidFinishNavigation will be called
171   // for any particular navigation before DidStartNavigation is called on the
172   // next.
DidStartNavigation(NavigationHandle * navigation_handle)173   virtual void DidStartNavigation(NavigationHandle* navigation_handle) {}
174 
175   // Called when a navigation encountered a server redirect.
DidRedirectNavigation(NavigationHandle * navigation_handle)176   virtual void DidRedirectNavigation(NavigationHandle* navigation_handle) {}
177 
178   // Called when the navigation is ready to be committed in a renderer. This
179   // occurs when the response code isn't 204/205 (which tell the browser that
180   // the request is successful but there's no content that follows) or a
181   // download (either from a response header or based on mime sniffing the
182   // response). The browser then is ready to switch rendering the new document.
183   // Most observers should use DidFinishNavigation instead, which happens right
184   // after the navigation commits. This method is for observers that want to
185   // initialize renderer-side state just before the RenderFrame commits the
186   // navigation.
187   //
188   // This is the first point in time where a RenderFrameHost is associated with
189   // the navigation.
ReadyToCommitNavigation(NavigationHandle * navigation_handle)190   virtual void ReadyToCommitNavigation(NavigationHandle* navigation_handle) {}
191 
192   // Called when a navigation finished in the WebContents. This happens when a
193   // navigation is committed, aborted or replaced by a new one. To know if the
194   // navigation has committed, use NavigationHandle::HasCommitted; use
195   // NavigationHandle::IsErrorPage to know if the navigation resulted in an
196   // error page.
197   //
198   // If this is called because the navigation committed, then the document load
199   // will still be ongoing in the RenderFrameHost returned by
200   // |navigation_handle|. Use the document loads events such as DidStopLoading
201   // and related methods to listen for continued events from this
202   // RenderFrameHost.
203   //
204   // Note that this is fired by same-document navigations, such as fragment
205   // navigations or pushState/replaceState, which will not result in a document
206   // change. To filter these out, use NavigationHandle::IsSameDocument.
207   //
208   // Note that |navigation_handle| will be destroyed at the end of this call,
209   // so do not keep a reference to it afterward.
210   //
211   // Note that using DidFinishNavigation to detect changes in the currently
212   // active document and reset per-document state is strongly discouraged.
213   // Please use RenderDocumentHostUserData to store such data instead.
214   // (In particular, the page might be stored in back-forward cache instead
215   // of being deleted. See the comment in RenderDocumentHostUserData for more
216   // details).
DidFinishNavigation(NavigationHandle * navigation_handle)217   virtual void DidFinishNavigation(NavigationHandle* navigation_handle) {}
218 
219   // Called after the contents replaces the |predecessor_contents| in its
220   // container due to portal activation. The |predecessor_contents| is now a
221   // portal pending adoption. |predecessor_contents| is non-null, but may
222   // subsequently be destroyed if it is not adopted.
223   // |activation_time| is the time the activation happened.
DidActivatePortal(WebContents * predecessor_web_contents,base::TimeTicks activation_time)224   virtual void DidActivatePortal(WebContents* predecessor_web_contents,
225                                  base::TimeTicks activation_time) {}
226 
227   // Document load events ------------------------------------------------------
228 
229   // These three methods correspond to the points in time when a document starts
230   // loading for the first time (initiates outgoing requests), when incoming
231   // data subsequently starts arriving, and when it finishes loading.
DidStartLoading()232   virtual void DidStartLoading() {}
DidReceiveResponse()233   virtual void DidReceiveResponse() {}
DidStopLoading()234   virtual void DidStopLoading() {}
235 
236   // The page has made some progress loading. |progress| is a value between 0.0
237   // (nothing loaded) to 1.0 (page fully loaded).
LoadProgressChanged(double progress)238   virtual void LoadProgressChanged(double progress) {}
239 
240   // This method is invoked once the window.document object of the main frame
241   // was created.
DocumentAvailableInMainFrame()242   virtual void DocumentAvailableInMainFrame() {}
243 
244   // This method is invoked once the onload handler of the main frame has
245   // completed.
246   // Prefer using WebContents::IsDocumentOnLoadCompletedInMainFrame instead
247   // of saving this state in your component.
DocumentOnLoadCompletedInMainFrame()248   virtual void DocumentOnLoadCompletedInMainFrame() {}
249 
250   // This method is invoked when the document in the given frame finished
251   // loading. At this point, scripts marked as defer were executed, and
252   // content scripts marked "document_end" get injected into the frame.
DOMContentLoaded(RenderFrameHost * render_frame_host)253   virtual void DOMContentLoaded(RenderFrameHost* render_frame_host) {}
254 
255   // This method is invoked when the load is done, i.e. the spinner of the tab
256   // will stop spinning, and the onload event was dispatched.
257   //
258   // If the WebContents is displaying replacement content, e.g. network error
259   // pages, DidFinishLoad is invoked for frames that were not sending
260   // navigational events before. It is safe to ignore these events.
DidFinishLoad(RenderFrameHost * render_frame_host,const GURL & validated_url)261   virtual void DidFinishLoad(RenderFrameHost* render_frame_host,
262                              const GURL& validated_url) {}
263 
264   // This method is like DidFinishLoad, but when the load failed or was
265   // cancelled, e.g. window.stop() is invoked.
DidFailLoad(RenderFrameHost * render_frame_host,const GURL & validated_url,int error_code)266   virtual void DidFailLoad(RenderFrameHost* render_frame_host,
267                            const GURL& validated_url,
268                            int error_code) {}
269 
270   // This method is invoked when the visible security state of the page changes.
DidChangeVisibleSecurityState()271   virtual void DidChangeVisibleSecurityState() {}
272 
273   // This method is invoked when content was loaded from an in-memory cache.
DidLoadResourceFromMemoryCache(const GURL & url,const std::string & mime_type,network::mojom::RequestDestination request_destination)274   virtual void DidLoadResourceFromMemoryCache(
275       const GURL& url,
276       const std::string& mime_type,
277       network::mojom::RequestDestination request_destination) {}
278 
279   // This method is invoked when a resource associate with the frame
280   // |render_frame_host| has been loaded, successfully or not. |request_id| will
281   // only be populated for main frame resources.
ResourceLoadComplete(RenderFrameHost * render_frame_host,const GlobalRequestID & request_id,const blink::mojom::ResourceLoadInfo & resource_load_info)282   virtual void ResourceLoadComplete(
283       RenderFrameHost* render_frame_host,
284       const GlobalRequestID& request_id,
285       const blink::mojom::ResourceLoadInfo& resource_load_info) {}
286 
287   // Called when document reads or sets a cookie (either via document.cookie or
288   // issuing a network request).
289   // Cookie reads/writes for a dedicated worker are attributed to the
290   // RenderFrameHost which created it.
OnCookiesAccessed(RenderFrameHost * render_frame_host,const CookieAccessDetails & details)291   virtual void OnCookiesAccessed(RenderFrameHost* render_frame_host,
292                                  const CookieAccessDetails& details) {}
293 
294   // Called when a network request issued by the navigation reads or sets a
295   // cookie. If a notification is received after the navigation has committed,
296   // it will be attributed to the RenderFrameHost created by the navigation.
OnCookiesAccessed(NavigationHandle * navigation_handle,const CookieAccessDetails & details)297   virtual void OnCookiesAccessed(NavigationHandle* navigation_handle,
298                                  const CookieAccessDetails& details) {}
299 
300   // This method is invoked when a new non-pending navigation entry is created.
301   // This corresponds to one NavigationController entry being created
302   // (in the case of new navigations) or renavigated to (for back/forward
303   // navigations).
NavigationEntryCommitted(const LoadCommittedDetails & load_details)304   virtual void NavigationEntryCommitted(
305       const LoadCommittedDetails& load_details) {}
306 
307   // Invoked when the NavigationController decreased its back/forward list count
308   // by removing entries from either the front or back of its list. This is
309   // usually the result of going back and then doing a new navigation, meaning
310   // all the "forward" items are deleted.
311   //
312   // This normally happens as a result of a new navigation. It will be
313   // followed by a NavigationEntryCommitted() call for the new page that
314   // caused the pruning. It could also be a result of removing an item from
315   // the list to delete history or fix up after interstitials.
NavigationListPruned(const PrunedDetails & pruned_details)316   virtual void NavigationListPruned(const PrunedDetails& pruned_details) {}
317 
318   // Invoked when NavigationEntries have been deleted because of a history
319   // deletion. Observers should ensure that they remove all traces of the
320   // deleted entries.
NavigationEntriesDeleted()321   virtual void NavigationEntriesDeleted() {}
322 
323   // Invoked when a NavigationEntry has changed.
324   //
325   // This will NOT be sent on navigation, interested parties should also
326   // implement NavigationEntryCommitted() to handle that case. This will be
327   // sent when the entry is updated outside of navigation (like when a new
328   // title comes).
NavigationEntryChanged(const EntryChangedDetails & change_details)329   virtual void NavigationEntryChanged(
330       const EntryChangedDetails& change_details) {}
331 
332   // This method is invoked when a new WebContents was created in response to
333   // an action in the observed WebContents, e.g. a link with target=_blank was
334   // clicked. The |source_render_frame_host| is the frame in which the action
335   // took place.
DidOpenRequestedURL(WebContents * new_contents,RenderFrameHost * source_render_frame_host,const GURL & url,const Referrer & referrer,WindowOpenDisposition disposition,ui::PageTransition transition,bool started_from_context_menu,bool renderer_initiated)336   virtual void DidOpenRequestedURL(WebContents* new_contents,
337                                    RenderFrameHost* source_render_frame_host,
338                                    const GURL& url,
339                                    const Referrer& referrer,
340                                    WindowOpenDisposition disposition,
341                                    ui::PageTransition transition,
342                                    bool started_from_context_menu,
343                                    bool renderer_initiated) {}
344 
345   // This method is invoked when the renderer process has completed its first
346   // paint after a non-empty layout.
DidFirstVisuallyNonEmptyPaint()347   virtual void DidFirstVisuallyNonEmptyPaint() {}
348 
349   // When WebContents::Stop() is called, the WebContents stops loading and then
350   // invokes this method. If there are ongoing navigations, their respective
351   // failure methods will also be invoked.
NavigationStopped()352   virtual void NavigationStopped() {}
353 
354   // Called when there has been direct user interaction with the WebContents.
355   // The type of the event specifies the kind of interaction. Direct user input
356   // signalled through this callback includes:
357   // 1) any mouse down event (blink::WebInputEvent::MouseDown);
358   // 2) the start of a scroll (blink::WebInputEvent::GestureScrollBegin);
359   // 3) any raw key down event (blink::WebInputEvent::RawKeyDown); and
360   // 4) any touch event (inc. scrolls) (blink::WebInputEvent::TouchStart).
DidGetUserInteraction(const blink::WebInputEvent & event)361   virtual void DidGetUserInteraction(const blink::WebInputEvent& event) {}
362 
363   // This method is invoked when a RenderViewHost of this WebContents was
364   // configured to ignore UI events, and an UI event took place.
DidGetIgnoredUIEvent()365   virtual void DidGetIgnoredUIEvent() {}
366 
367   // Invoked every time the WebContents changes visibility.
OnVisibilityChanged(Visibility visibility)368   virtual void OnVisibilityChanged(Visibility visibility) {}
369 
370   // Invoked when the main frame changes size.
MainFrameWasResized(bool width_changed)371   virtual void MainFrameWasResized(bool width_changed) {}
372 
373   // Invoked when the given frame changes its window.name property.
FrameNameChanged(RenderFrameHost * render_frame_host,const std::string & name)374   virtual void FrameNameChanged(RenderFrameHost* render_frame_host,
375                                 const std::string& name) {}
376 
377   // Called when the sticky user activation bit has been set on the frame.
378   // This will not be called for new RenderFrameHosts whose underlying
379   // FrameTreeNode was already activated. This should not be used to determine a
380   // RenderFrameHost's user activation state.
FrameReceivedFirstUserActivation(RenderFrameHost * render_frame_host)381   virtual void FrameReceivedFirstUserActivation(
382       RenderFrameHost* render_frame_host) {}
383 
384   // Invoked when the display state of the frame changes.
FrameDisplayStateChanged(RenderFrameHost * render_frame_host,bool is_display_none)385   virtual void FrameDisplayStateChanged(RenderFrameHost* render_frame_host,
386                                         bool is_display_none) {}
387 
388   // Invoked when a frame changes size.
FrameSizeChanged(RenderFrameHost * render_frame_host,const gfx::Size & frame_size)389   virtual void FrameSizeChanged(RenderFrameHost* render_frame_host,
390                                 const gfx::Size& frame_size) {}
391 
392   // This method is invoked when the title of the WebContents is set. Note that
393   // |entry| may be null if the web page whose title changed has not yet had a
394   // NavigationEntry assigned to it.
TitleWasSet(NavigationEntry * entry)395   virtual void TitleWasSet(NavigationEntry* entry) {}
396 
AppCacheAccessed(const GURL & manifest_url,bool blocked_by_policy)397   virtual void AppCacheAccessed(const GURL& manifest_url,
398                                 bool blocked_by_policy) {}
399 
400   // These methods are invoked when a Pepper plugin instance is created/deleted
401   // in the DOM.
PepperInstanceCreated()402   virtual void PepperInstanceCreated() {}
PepperInstanceDeleted()403   virtual void PepperInstanceDeleted() {}
404 
405   // This method is called when the viewport fit of a WebContents changes.
ViewportFitChanged(blink::mojom::ViewportFit value)406   virtual void ViewportFitChanged(blink::mojom::ViewportFit value) {}
407 
408   // Notification that a plugin has crashed.
409   // |plugin_pid| is the process ID identifying the plugin process. Note that
410   // this ID is supplied by the renderer process, so should not be trusted.
411   // Besides, the corresponding process has probably died at this point. The ID
412   // may even have been reused by a new process.
PluginCrashed(const base::FilePath & plugin_path,base::ProcessId plugin_pid)413   virtual void PluginCrashed(const base::FilePath& plugin_path,
414                              base::ProcessId plugin_pid) {}
415 
416   // Notification that the given plugin has hung or become unhung. This
417   // notification is only for Pepper plugins.
418   //
419   // The plugin_child_id is the unique child process ID from the plugin. Note
420   // that this ID is supplied by the renderer process, so should be validated
421   // before it's used for anything in case there's an exploited renderer
422   // process.
PluginHungStatusChanged(int plugin_child_id,const base::FilePath & plugin_path,bool is_hung)423   virtual void PluginHungStatusChanged(int plugin_child_id,
424                                        const base::FilePath& plugin_path,
425                                        bool is_hung) {}
426 
427   // Notifies that an inner WebContents instance has been created with the
428   // observed WebContents as its container. |inner_web_contents| has not been
429   // added to the WebContents tree at this point, but can be observed safely.
InnerWebContentsCreated(WebContents * inner_web_contents)430   virtual void InnerWebContentsCreated(WebContents* inner_web_contents) {}
431 
432   // Notifies that an |inner_web_contents| instance has been attached to the
433   // provided |render_frame_host|. By the time this is called the
434   // |inner_web_contents| will have been added to the WebContents tree.
InnerWebContentsAttached(WebContents * inner_web_contents,RenderFrameHost * render_frame_host,bool is_full_page)435   virtual void InnerWebContentsAttached(WebContents* inner_web_contents,
436                                         RenderFrameHost* render_frame_host,
437                                         bool is_full_page) {}
438 
439   // Notifies that an |inner_web_contents| instance has been detached from this
440   // WebContents. InnerWebContentsAttached() will already have been called for
441   // the |inner_web_contents|. By the time this is called the
442   // |inner_web_contents| will have been removed from the WebContents tree, but
443   // will still be alive and is safe to observe.
InnerWebContentsDetached(WebContents * inner_web_contents)444   virtual void InnerWebContentsDetached(WebContents* inner_web_contents) {}
445 
446   // Invoked when WebContents::Clone() was used to clone a WebContents.
DidCloneToNewWebContents(WebContents * old_web_contents,WebContents * new_web_contents)447   virtual void DidCloneToNewWebContents(WebContents* old_web_contents,
448                                         WebContents* new_web_contents) {}
449 
450   // Invoked when the WebContents is being destroyed. Gives subclasses a chance
451   // to cleanup. After the whole loop over all WebContentsObservers has been
452   // finished, web_contents() returns nullptr.
WebContentsDestroyed()453   virtual void WebContentsDestroyed() {}
454 
455   // Called when the user agent override for a WebContents has been changed.
UserAgentOverrideSet(const blink::UserAgentOverride & ua_override)456   virtual void UserAgentOverrideSet(
457       const blink::UserAgentOverride& ua_override) {}
458 
459   // Invoked when new blink::mojom::FaviconURLPtr candidates are received from
460   // the renderer process. If the instance is created after the page is loaded,
461   // it is recommended to call WebContents::GetFaviconURLs() to get the current
462   // list as this callback will not be executed unless there is an update.
463   // |render_frame_host| is the main render frame host.
DidUpdateFaviconURL(RenderFrameHost * render_frame_host,const std::vector<blink::mojom::FaviconURLPtr> & candidates)464   virtual void DidUpdateFaviconURL(
465       RenderFrameHost* render_frame_host,
466       const std::vector<blink::mojom::FaviconURLPtr>& candidates) {}
467 
468   // Called when an audio change occurs to this WebContents. If |audible| is
469   // true then one or more frames or child contents are emitting audio; if
470   // false, then no frames or child contents are emitting audio. See
471   // OnFrameAudioStateChanged for per-frame information.
OnAudioStateChanged(bool audible)472   virtual void OnAudioStateChanged(bool audible) {}
473 
474   // Called when the audio state of an individual frame changes.
OnFrameAudioStateChanged(RenderFrameHost * rfh,bool audible)475   virtual void OnFrameAudioStateChanged(RenderFrameHost* rfh, bool audible) {}
476 
477   // Called when the connected to Bluetooth device state changes.
OnIsConnectedToBluetoothDeviceChanged(bool is_connected_to_bluetooth_device)478   virtual void OnIsConnectedToBluetoothDeviceChanged(
479       bool is_connected_to_bluetooth_device) {}
480 
481   // Invoked when the WebContents is muted/unmuted.
DidUpdateAudioMutingState(bool muted)482   virtual void DidUpdateAudioMutingState(bool muted) {}
483 
484   // Invoked when the renderer process has toggled the tab into/out of
485   // fullscreen mode.
DidToggleFullscreenModeForTab(bool entered_fullscreen,bool will_cause_resize)486   virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen,
487                                              bool will_cause_resize) {}
488 
489   // Signals that |rfh| has the current fullscreen element. This is invoked
490   // when:
491   //  1) an element in this frame enters fullscreen or in nested fullscreen, or
492   //  2) after an element in a descendant frame exits fullscreen and makes
493   //     this frame own the current fullscreen element again.
DidAcquireFullscreen(RenderFrameHost * rfh)494   virtual void DidAcquireFullscreen(RenderFrameHost* rfh) {}
495 
496   // Invoked when the vertical scroll direction of the root layer is changed.
497   // Note that if a scroll in a given direction occurs, the scroll is completed,
498   // and then another scroll in the *same* direction occurs, we will not
499   // consider the second scroll event to have caused a change in direction. Also
500   // note that this API will *never* be called with |kNull| which only exists to
501   // indicate the absence of a vertical scroll direction.
DidChangeVerticalScrollDirection(viz::VerticalScrollDirection scroll_direction)502   virtual void DidChangeVerticalScrollDirection(
503       viz::VerticalScrollDirection scroll_direction) {}
504 
505   // Invoked before a form repost warning is shown.
BeforeFormRepostWarningShow()506   virtual void BeforeFormRepostWarningShow() {}
507 
508   // Invoked when the beforeunload handler fires. |proceed| is set to true if
509   // the beforeunload can safely proceed, otherwise it should be interrupted.
510   // The time is from the renderer process.
BeforeUnloadFired(bool proceed,const base::TimeTicks & proceed_time)511   virtual void BeforeUnloadFired(bool proceed,
512                                  const base::TimeTicks& proceed_time) {}
513 
514   // Invoked when a user cancels a before unload dialog.
BeforeUnloadDialogCancelled()515   virtual void BeforeUnloadDialogCancelled() {}
516 
517   // Called whenever the AXTreeID for the main frame has changed.
AXTreeIDForMainFrameHasChanged()518   virtual void AXTreeIDForMainFrameHasChanged() {}
519 
520   // Called when accessibility events or location changes are received
521   // from a render frame, but only when the accessibility mode has the
522   // ui::AXMode::kWebContents flag set.
AccessibilityEventReceived(const AXEventNotificationDetails & details)523   virtual void AccessibilityEventReceived(
524       const AXEventNotificationDetails& details) {}
AccessibilityLocationChangesReceived(const std::vector<AXLocationChangeNotificationDetails> & details)525   virtual void AccessibilityLocationChangesReceived(
526       const std::vector<AXLocationChangeNotificationDetails>& details) {}
527 
528   // Invoked when theme color is changed.
DidChangeThemeColor()529   virtual void DidChangeThemeColor() {}
530 
531   // Invoked when background color is changed.
OnBackgroundColorChanged()532   virtual void OnBackgroundColorChanged() {}
533 
534   // Called when a message is added to the console of the WebContents. This is
535   // invoked before forwarding the message to the WebContents' delegate.
OnDidAddMessageToConsole(RenderFrameHost * source_frame,blink::mojom::ConsoleMessageLevel log_level,const base::string16 & message,int32_t line_no,const base::string16 & source_id)536   virtual void OnDidAddMessageToConsole(
537       RenderFrameHost* source_frame,
538       blink::mojom::ConsoleMessageLevel log_level,
539       const base::string16& message,
540       int32_t line_no,
541       const base::string16& source_id) {}
542 
543   // Invoked when media is playing or paused.  |id| is unique per player and per
544   // RenderFrameHost.  There may be multiple players within a RenderFrameHost
545   // and subsequently within a WebContents.  MediaStartedPlaying() will always
546   // be followed by MediaStoppedPlaying() after player teardown.  Observers must
547   // release all stored copies of |id| when MediaStoppedPlaying() is received.
548   // |has_video| and |has_audio| can both be false in cases where the media
549   // is playing muted and should be considered as inaudible for all intent and
550   // purposes.
551   struct MediaPlayerInfo {
MediaPlayerInfoMediaPlayerInfo552     MediaPlayerInfo(bool has_video, bool has_audio)
553         : has_video(has_video), has_audio(has_audio) {}
554     bool has_video;
555     bool has_audio;
556   };
557 
MediaStartedPlaying(const MediaPlayerInfo & video_type,const MediaPlayerId & id)558   virtual void MediaStartedPlaying(const MediaPlayerInfo& video_type,
559                                    const MediaPlayerId& id) {}
560   enum class MediaStoppedReason {
561     // The media was stopped for an unspecified reason.
562     kUnspecified,
563 
564     // The media was stopped because it reached the end of the stream.
565     kReachedEndOfStream,
566   };
MediaStoppedPlaying(const MediaPlayerInfo & video_type,const MediaPlayerId & id,WebContentsObserver::MediaStoppedReason reason)567   virtual void MediaStoppedPlaying(
568       const MediaPlayerInfo& video_type,
569       const MediaPlayerId& id,
570       WebContentsObserver::MediaStoppedReason reason) {}
MediaResized(const gfx::Size & size,const MediaPlayerId & id)571   virtual void MediaResized(const gfx::Size& size, const MediaPlayerId& id) {}
572   // Invoked when media enters or exits fullscreen. We must use a heuristic
573   // to determine this as it is not trivial for media with custom controls.
574   // There is a slight delay between media entering or exiting fullscreen
575   // and it being detected.
MediaEffectivelyFullscreenChanged(bool is_fullscreen)576   virtual void MediaEffectivelyFullscreenChanged(bool is_fullscreen) {}
MediaPictureInPictureChanged(bool is_picture_in_picture)577   virtual void MediaPictureInPictureChanged(bool is_picture_in_picture) {}
MediaMutedStatusChanged(const MediaPlayerId & id,bool muted)578   virtual void MediaMutedStatusChanged(const MediaPlayerId& id, bool muted) {}
MediaBufferUnderflow(const MediaPlayerId & id)579   virtual void MediaBufferUnderflow(const MediaPlayerId& id) {}
MediaPlayerSeek(const MediaPlayerId & id)580   virtual void MediaPlayerSeek(const MediaPlayerId& id) {}
581 
582   // Invoked when the renderer process changes the page scale factor.
OnPageScaleFactorChanged(float page_scale_factor)583   virtual void OnPageScaleFactorChanged(float page_scale_factor) {}
584 
585   // Invoked when a paste event occurs.
OnPaste()586   virtual void OnPaste() {}
587 
588   // Invoked if an IPC message is coming from a specific RenderFrameHost.
589   virtual bool OnMessageReceived(const IPC::Message& message,
590                                  RenderFrameHost* render_frame_host);
591 
592   // Notification that the |render_widget_host| for this WebContents has gained
593   // focus.
OnWebContentsFocused(RenderWidgetHost * render_widget_host)594   virtual void OnWebContentsFocused(RenderWidgetHost* render_widget_host) {}
595 
596   // Notification that the |render_widget_host| for this WebContents has lost
597   // focus.
OnWebContentsLostFocus(RenderWidgetHost * render_widget_host)598   virtual void OnWebContentsLostFocus(RenderWidgetHost* render_widget_host) {}
599 
600   // Notification that a RenderFrameHost inside this WebContents has updated
601   // its focused element. |details| contains information on the element
602   // that has received focus. This allows for observing focus changes
603   // within WebContents, as opposed to OnWebContentsFocused/LostFocus
604   // which allows observation that the RenderWidgetHost for the
605   // WebContents has gained/lost focus.
OnFocusChangedInPage(FocusedNodeDetails * details)606   virtual void OnFocusChangedInPage(FocusedNodeDetails* details) {}
607 
608   // Notifies that the manifest URL for the main frame changed to
609   // |manifest_url|. This will be invoked when a document with a manifest loads
610   // or when the manifest URL changes (possibly to nothing). It is not invoked
611   // when a document with no manifest loads. During document load, if the
612   // document has both a manifest and a favicon, DidUpdateWebManifestURL() will
613   // be invoked before DidUpdateFaviconURL().
DidUpdateWebManifestURL(RenderFrameHost * target_frame,const base::Optional<GURL> & manifest_url)614   virtual void DidUpdateWebManifestURL(
615       RenderFrameHost* target_frame,
616       const base::Optional<GURL>& manifest_url) {}
617 
618   // DEPRECATED. Please register interface binders with BrowserInterfaceBroker
619   // instead (see 'Interface-Brokers' section in //docs/mojo_and_services.md).
620   // Called to give the embedder an opportunity to bind an interface request
621   // from a frame. If the request can be bound, |interface_pipe| will be taken.
OnInterfaceRequestFromFrame(RenderFrameHost * render_frame_host,const std::string & interface_name,mojo::ScopedMessagePipeHandle * interface_pipe)622   virtual void OnInterfaceRequestFromFrame(
623       RenderFrameHost* render_frame_host,
624       const std::string& interface_name,
625       mojo::ScopedMessagePipeHandle* interface_pipe) {}
626 
627   // Called when "audible" playback starts or stops on a WebAudio AudioContext.
628   using AudioContextId = std::pair<RenderFrameHost*, int>;
AudioContextPlaybackStarted(const AudioContextId & audio_context_id)629   virtual void AudioContextPlaybackStarted(
630       const AudioContextId& audio_context_id) {}
AudioContextPlaybackStopped(const AudioContextId & audio_context_id)631   virtual void AudioContextPlaybackStopped(
632       const AudioContextId& audio_context_id) {}
633 
634   // Called when the RenderFrameHost tries to use a ServiceWorker
635   // (e.g. via navigation.serviceWorker API).
OnServiceWorkerAccessed(RenderFrameHost * render_frame_host,const GURL & scope,AllowServiceWorkerResult allowed)636   virtual void OnServiceWorkerAccessed(RenderFrameHost* render_frame_host,
637                                        const GURL& scope,
638                                        AllowServiceWorkerResult allowed) {}
639   // Called when the NavigationHandle accesses ServiceWorker to see if the
640   // network request should be handled by the ServiceWorker instead
641   // (e.g. for navigations to URLs which are in scope of a ServiceWorker).
OnServiceWorkerAccessed(NavigationHandle * navigation_handle,const GURL & scope,AllowServiceWorkerResult allowed)642   virtual void OnServiceWorkerAccessed(NavigationHandle* navigation_handle,
643                                        const GURL& scope,
644                                        AllowServiceWorkerResult allowed) {}
645   virtual bool ShowPopupMenu(
646       RenderFrameHost* render_frame_host,
647       mojo::PendingRemote<blink::mojom::PopupMenuClient>* popup_client,
648       const gfx::Rect& bounds,
649       int32_t item_height,
650       double font_size,
651       int32_t selected_item,
652       std::vector<blink::mojom::MenuItemPtr>* menu_items,
653       bool right_aligned,
654       bool allow_multiple_selection);
655 
656   // IPC::Listener implementation.
657   // DEPRECATED: Use (i.e. override) the other overload instead:
658   //     virtual bool OnMessageReceived(const IPC::Message& message,
659   //                                    RenderFrameHost* render_frame_host);
660   // TODO(https://crbug.com/758026): Delete this overload when possible.
661   bool OnMessageReceived(const IPC::Message& message) override;
662 
663   WebContents* web_contents() const;
664 
665  protected:
666   // Use this constructor when the object is tied to a single WebContents for
667   // its entire lifetime.
668   explicit WebContentsObserver(WebContents* web_contents);
669 
670   // Use this constructor when the object wants to observe a WebContents for
671   // part of its lifetime.  It can then call Observe() to start and stop
672   // observing.
673   WebContentsObserver();
674 
675   ~WebContentsObserver() override;
676 
677   // Start observing a different WebContents; used with the default constructor.
678   void Observe(WebContents* web_contents);
679 
680  private:
681   friend class WebContentsImpl;
682 
683   void ResetWebContents();
684 
685   WebContentsImpl* web_contents_;
686 
687   DISALLOW_COPY_AND_ASSIGN(WebContentsObserver);
688 };
689 
690 }  // namespace content
691 
692 #endif  // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_OBSERVER_H_
693