• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
set_allow_extension_scheme(bool allow_extension_scheme)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