Home | History | Annotate | Download | only in web_navigation
      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 // Defines the Chrome Extensions WebNavigation API functions for observing and
      6 // intercepting navigation events, as specified in the extension JSON API.
      7 
      8 #ifndef CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_
      9 #define CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_
     10 
     11 #include <map>
     12 #include <set>
     13 
     14 #include "base/compiler_specific.h"
     15 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
     16 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
     17 #include "chrome/browser/extensions/event_router.h"
     18 #include "chrome/browser/extensions/extension_function.h"
     19 #include "chrome/browser/profiles/profile.h"
     20 #include "chrome/browser/ui/browser_list_observer.h"
     21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     22 #include "content/public/browser/notification_observer.h"
     23 #include "content/public/browser/notification_registrar.h"
     24 #include "content/public/browser/web_contents_observer.h"
     25 #include "content/public/browser/web_contents_user_data.h"
     26 #include "url/gurl.h"
     27 
     28 struct RetargetingDetails;
     29 
     30 namespace extensions {
     31 
     32 // Tab contents observer that forwards navigation events to the event router.
     33 class WebNavigationTabObserver
     34     : public content::NotificationObserver,
     35       public content::WebContentsObserver,
     36       public content::WebContentsUserData<WebNavigationTabObserver> {
     37  public:
     38   virtual ~WebNavigationTabObserver();
     39 
     40   // Returns the object for the given |web_contents|.
     41   static WebNavigationTabObserver* Get(content::WebContents* web_contents);
     42 
     43   const FrameNavigationState& frame_navigation_state() const {
     44     return navigation_state_;
     45   }
     46 
     47   content::RenderViewHost* GetRenderViewHostInProcess(int process_id) const;
     48 
     49   // content::NotificationObserver implementation.
     50   virtual void Observe(int type,
     51                        const content::NotificationSource& source,
     52                        const content::NotificationDetails& details) OVERRIDE;
     53 
     54   // content::WebContentsObserver implementation.
     55   virtual void RenderViewDeleted(
     56       content::RenderViewHost* render_view_host) OVERRIDE;
     57   virtual void AboutToNavigateRenderView(
     58       content::RenderViewHost* render_view_host) OVERRIDE;
     59   virtual void DidStartProvisionalLoadForFrame(
     60       int64 frame_num,
     61       int64 parent_frame_num,
     62       bool is_main_frame,
     63       const GURL& validated_url,
     64       bool is_error_page,
     65       bool is_iframe_srcdoc,
     66       content::RenderViewHost* render_view_host) OVERRIDE;
     67   virtual void DidCommitProvisionalLoadForFrame(
     68       int64 frame_num,
     69       bool is_main_frame,
     70       const GURL& url,
     71       content::PageTransition transition_type,
     72       content::RenderViewHost* render_view_host) OVERRIDE;
     73   virtual void DidFailProvisionalLoad(
     74       int64 frame_num,
     75       bool is_main_frame,
     76       const GURL& validated_url,
     77       int error_code,
     78       const string16& error_description,
     79       content::RenderViewHost* render_view_host) OVERRIDE;
     80   virtual void DocumentLoadedInFrame(
     81       int64 frame_num,
     82       content::RenderViewHost* render_view_host) OVERRIDE;
     83   virtual void DidFinishLoad(
     84       int64 frame_num,
     85       const GURL& validated_url,
     86       bool is_main_frame,
     87       content::RenderViewHost* render_view_host) OVERRIDE;
     88   virtual void DidFailLoad(
     89       int64 frame_num,
     90       const GURL& validated_url,
     91       bool is_main_frame,
     92       int error_code,
     93       const string16& error_description,
     94       content::RenderViewHost* render_view_host) OVERRIDE;
     95   virtual void DidOpenRequestedURL(content::WebContents* new_contents,
     96                                    const GURL& url,
     97                                    const content::Referrer& referrer,
     98                                    WindowOpenDisposition disposition,
     99                                    content::PageTransition transition,
    100                                    int64 source_frame_num) OVERRIDE;
    101   virtual void FrameDetached(content::RenderViewHost* render_view_host,
    102                              int64 frame_num) OVERRIDE;
    103   virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
    104 
    105  private:
    106   explicit WebNavigationTabObserver(content::WebContents* web_contents);
    107   friend class content::WebContentsUserData<WebNavigationTabObserver>;
    108 
    109   // True if the transition and target url correspond to a reference fragment
    110   // navigation.
    111   bool IsReferenceFragmentNavigation(FrameNavigationState::FrameID frame_id,
    112                                      const GURL& url);
    113 
    114   // Creates and sends onErrorOccurred events for all on-going navigations. If
    115   // |render_view_host| is non-NULL, only generates events for frames in this
    116   // render view host. If |id_to_skip| is given, no events are sent for that
    117   // frame.
    118   void SendErrorEvents(content::WebContents* web_contents,
    119                        content::RenderViewHost* render_view_host,
    120                        FrameNavigationState::FrameID id_to_skip);
    121 
    122   // Tracks the state of the frames we are sending events for.
    123   FrameNavigationState navigation_state_;
    124 
    125   // Used for tracking registrations to redirect notifications.
    126   content::NotificationRegistrar registrar_;
    127 
    128   // The current RenderViewHost of the observed WebContents.
    129   content::RenderViewHost* render_view_host_;
    130 
    131   // During a cross site navigation, the WebContents has a second, pending
    132   // RenderViewHost.
    133   content::RenderViewHost* pending_render_view_host_;
    134 
    135   DISALLOW_COPY_AND_ASSIGN(WebNavigationTabObserver);
    136 };
    137 
    138 // Observes navigation notifications and routes them as events to the extension
    139 // system.
    140 class WebNavigationEventRouter : public TabStripModelObserver,
    141                                  public chrome::BrowserListObserver,
    142                                  public content::NotificationObserver {
    143  public:
    144   explicit WebNavigationEventRouter(Profile* profile);
    145   virtual ~WebNavigationEventRouter();
    146 
    147  private:
    148   // Used to cache the information about newly created WebContents objects.
    149   struct PendingWebContents{
    150     PendingWebContents();
    151     PendingWebContents(content::WebContents* source_web_contents,
    152                        int64 source_frame_id,
    153                        bool source_frame_is_main_frame,
    154                        content::WebContents* target_web_contents,
    155                        const GURL& target_url);
    156     ~PendingWebContents();
    157 
    158     content::WebContents* source_web_contents;
    159     int64 source_frame_id;
    160     bool source_frame_is_main_frame;
    161     content::WebContents* target_web_contents;
    162     GURL target_url;
    163   };
    164 
    165   // TabStripModelObserver implementation.
    166   virtual void TabReplacedAt(TabStripModel* tab_strip_model,
    167                              content::WebContents* old_contents,
    168                              content::WebContents* new_contents,
    169                              int index) OVERRIDE;
    170 
    171   // chrome::BrowserListObserver implementation.
    172   virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
    173   virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
    174 
    175   // content::NotificationObserver implementation.
    176   virtual void Observe(int type,
    177                        const content::NotificationSource& source,
    178                        const content::NotificationDetails& details) OVERRIDE;
    179 
    180   // Handler for the NOTIFICATION_RETARGETING event. The method takes the
    181   // details of such an event and stores them for the later
    182   // NOTIFICATION_TAB_ADDED event.
    183   void Retargeting(const RetargetingDetails* details);
    184 
    185   // Handler for the NOTIFICATION_TAB_ADDED event. The method takes the details
    186   // of such an event and creates a JSON formated extension event from it.
    187   void TabAdded(content::WebContents* tab);
    188 
    189   // Handler for NOTIFICATION_WEB_CONTENTS_DESTROYED. If |tab| is in
    190   // |pending_web_contents_|, it is removed.
    191   void TabDestroyed(content::WebContents* tab);
    192 
    193   // Mapping pointers to WebContents objects to information about how they got
    194   // created.
    195   std::map<content::WebContents*, PendingWebContents> pending_web_contents_;
    196 
    197   // Used for tracking registrations to navigation notifications.
    198   content::NotificationRegistrar registrar_;
    199 
    200   // The profile that owns us via ExtensionService.
    201   Profile* profile_;
    202 
    203   DISALLOW_COPY_AND_ASSIGN(WebNavigationEventRouter);
    204 };
    205 
    206 // API function that returns the state of a given frame.
    207 class WebNavigationGetFrameFunction : public SyncExtensionFunction {
    208   virtual ~WebNavigationGetFrameFunction() {}
    209   virtual bool RunImpl() OVERRIDE;
    210   DECLARE_EXTENSION_FUNCTION("webNavigation.getFrame", WEBNAVIGATION_GETFRAME)
    211 };
    212 
    213 // API function that returns the states of all frames in a given tab.
    214 class WebNavigationGetAllFramesFunction : public SyncExtensionFunction {
    215   virtual ~WebNavigationGetAllFramesFunction() {}
    216   virtual bool RunImpl() OVERRIDE;
    217   DECLARE_EXTENSION_FUNCTION("webNavigation.getAllFrames",
    218                              WEBNAVIGATION_GETALLFRAMES)
    219 };
    220 
    221 class WebNavigationAPI : public ProfileKeyedAPI,
    222                          public extensions::EventRouter::Observer {
    223  public:
    224   explicit WebNavigationAPI(Profile* profile);
    225   virtual ~WebNavigationAPI();
    226 
    227   // BrowserContextKeyedService implementation.
    228   virtual void Shutdown() OVERRIDE;
    229 
    230   // ProfileKeyedAPI implementation.
    231   static ProfileKeyedAPIFactory<WebNavigationAPI>* GetFactoryInstance();
    232 
    233   // EventRouter::Observer implementation.
    234   virtual void OnListenerAdded(const extensions::EventListenerInfo& details)
    235       OVERRIDE;
    236 
    237  private:
    238   friend class ProfileKeyedAPIFactory<WebNavigationAPI>;
    239 
    240   Profile* profile_;
    241 
    242   // ProfileKeyedAPI implementation.
    243   static const char* service_name() {
    244     return "WebNavigationAPI";
    245   }
    246   static const bool kServiceIsNULLWhileTesting = true;
    247 
    248   // Created lazily upon OnListenerAdded.
    249   scoped_ptr<WebNavigationEventRouter> web_navigation_event_router_;
    250 
    251   DISALLOW_COPY_AND_ASSIGN(WebNavigationAPI);
    252 };
    253 
    254 }  // namespace extensions
    255 
    256 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_
    257