Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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
      7 // chrome/common/extensions/api/extension_api.json.
      8 
      9 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_
     10 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_
     11 #pragma once
     12 
     13 #include <map>
     14 
     15 #include "base/memory/singleton.h"
     16 #include "chrome/browser/extensions/extension_function.h"
     17 #include "content/browser/tab_contents/tab_contents_observer.h"
     18 #include "content/common/notification_observer.h"
     19 #include "content/common/notification_registrar.h"
     20 #include "googleurl/src/gurl.h"
     21 
     22 class TabContents;
     23 struct ViewHostMsg_CreateWindow_Params;
     24 
     25 // Tracks the navigation state of all frames currently known to the
     26 // webNavigation API. It is mainly used to track in which frames an error
     27 // occurred so no further events for this frame are being sent.
     28 class FrameNavigationState {
     29  public:
     30   FrameNavigationState();
     31   ~FrameNavigationState();
     32 
     33   // True if navigation events for the given frame can be sent.
     34   bool CanSendEvents(int64 frame_id) const;
     35 
     36   // Starts to track a frame given by its |frame_id| showing the URL |url| in
     37   // a |tab_contents|.
     38   void TrackFrame(int64 frame_id,
     39                   const GURL& url,
     40                   bool is_main_frame,
     41                   bool is_error_page,
     42                   const TabContents* tab_contents);
     43 
     44   // Returns the URL corresponding to a tracked frame given by its |frame_id|.
     45   GURL GetUrl(int64 frame_id) const;
     46 
     47   // True if the frame given by its |frame_id| is the main frame of its tab.
     48   bool IsMainFrame(int64 frame_id) const;
     49 
     50   // Marks a frame as in an error state.
     51   void ErrorOccurredInFrame(int64 frame_id);
     52 
     53   // Removes state associated with this tab contents and all of its frames.
     54   void RemoveTabContentsState(const TabContents* tab_contents);
     55 
     56 #ifdef UNIT_TEST
     57   static void set_allow_extension_scheme(bool allow_extension_scheme) {
     58     allow_extension_scheme_ = allow_extension_scheme;
     59   }
     60 #endif
     61 
     62  private:
     63   typedef std::multimap<const TabContents*, int64> TabContentsToFrameIdMap;
     64   struct FrameState {
     65     bool error_occurred;  // True if an error has occurred in this frame.
     66     bool is_main_frame;  // True if this is a main frame.
     67     GURL url;  // URL of this frame.
     68   };
     69   typedef std::map<int64, FrameState> FrameIdToStateMap;
     70 
     71   // Tracks which frames belong to a given tab contents object.
     72   TabContentsToFrameIdMap tab_contents_map_;
     73 
     74   // Tracks the state of known frames.
     75   FrameIdToStateMap frame_state_map_;
     76 
     77   // If true, also allow events from chrome-extension:// URLs.
     78   static bool allow_extension_scheme_;
     79 
     80   DISALLOW_COPY_AND_ASSIGN(FrameNavigationState);
     81 };
     82 
     83 // Tab contents observer that forwards navigation events to the event router.
     84 class ExtensionWebNavigationTabObserver : public TabContentsObserver {
     85  public:
     86   explicit ExtensionWebNavigationTabObserver(TabContents* tab_contents);
     87   virtual ~ExtensionWebNavigationTabObserver();
     88 
     89   // TabContentsObserver implementation.
     90   virtual void DidStartProvisionalLoadForFrame(int64 frame_id,
     91                                                  bool is_main_frame,
     92                                                  const GURL& validated_url,
     93                                                  bool is_error_page) OVERRIDE;
     94   virtual void DidCommitProvisionalLoadForFrame(
     95       int64 frame_id,
     96       bool is_main_frame,
     97       const GURL& url,
     98       PageTransition::Type transition_type) OVERRIDE;
     99   virtual void DidFailProvisionalLoad(int64 frame_id,
    100                                       bool is_main_frame,
    101                                       const GURL& validated_url,
    102                                       int error_code) OVERRIDE;
    103   virtual void DocumentLoadedInFrame(int64 frame_id) OVERRIDE;
    104   virtual void DidFinishLoad(int64 frame_id) OVERRIDE;
    105   virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE;
    106   virtual void DidOpenURL(const GURL& url,
    107                           const GURL& referrer,
    108                           WindowOpenDisposition disposition,
    109                           PageTransition::Type transition);
    110 
    111 
    112  private:
    113   // True if the transition and target url correspond to a reference fragment
    114   // navigation.
    115   bool IsReferenceFragmentNavigation(int64 frame_id, const GURL& url);
    116 
    117   // Simulates a complete series of events for reference fragment navigations.
    118   void NavigatedReferenceFragment(int64 frame_id,
    119                                   bool is_main_frame,
    120                                   const GURL& url,
    121                                   PageTransition::Type transition_type);
    122 
    123   // Tracks the state of the frames we are sending events for.
    124   FrameNavigationState navigation_state_;
    125 
    126   DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationTabObserver);
    127 };
    128 
    129 // Observes navigation notifications and routes them as events to the extension
    130 // system.
    131 class ExtensionWebNavigationEventRouter : public NotificationObserver {
    132  public:
    133   // Returns the singleton instance of the event router.
    134   static ExtensionWebNavigationEventRouter* GetInstance();
    135 
    136   // Invoked by the extensions service once the extension system is fully set
    137   // up and can start dispatching events to extensions.
    138   void Init();
    139 
    140  private:
    141   friend struct DefaultSingletonTraits<ExtensionWebNavigationEventRouter>;
    142 
    143   ExtensionWebNavigationEventRouter();
    144   virtual ~ExtensionWebNavigationEventRouter();
    145 
    146   // NotificationObserver implementation.
    147   virtual void Observe(NotificationType type,
    148                        const NotificationSource& source,
    149                        const NotificationDetails& details);
    150 
    151   // Handler for the CREATING_NEW_WINDOW event. The method takes the details of
    152   // such an event and constructs a suitable JSON formatted extension event from
    153   // it.
    154   void CreatingNewWindow(TabContents* tab_content,
    155                          const ViewHostMsg_CreateWindow_Params* details);
    156 
    157   // Used for tracking registrations to navigation notifications.
    158   NotificationRegistrar registrar_;
    159 
    160   DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationEventRouter);
    161 };
    162 
    163 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_
    164