Home | History | Annotate | Download | only in browser
      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 
     17 namespace content {
     18 
     19 class RenderViewHost;
     20 class WebContents;
     21 class WebContentsImpl;
     22 struct FaviconURL;
     23 struct FrameNavigateParams;
     24 struct LoadCommittedDetails;
     25 struct 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
     40 class 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 process for the current RenderView crashes.
     60   // The WebContents continues to use the RenderViewHost, e.g. when the user
     61   // reloads the current page.
     62   // When the RenderViewHost is deleted, the RenderViewDeleted method will be
     63   // invoked.
     64   virtual void RenderProcessGone(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