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.
5 // Defines the Chrome Extensions WebNavigation API functions for observing and
6 // intercepting navigation events, as specified in the extension JSON API.
8 #ifndef CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_
9 #define CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_
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/chrome_extension_function.h"
18 #include "chrome/browser/extensions/event_router.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"
28 struct RetargetingDetails;
30 namespace extensions {
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> {
38 virtual ~WebNavigationTabObserver();
40 // Returns the object for the given |web_contents|.
41 static WebNavigationTabObserver* Get(content::WebContents* web_contents);
43 const FrameNavigationState& frame_navigation_state() const {
44 return navigation_state_;
47 content::RenderViewHost* GetRenderViewHostInProcess(int process_id) const;
49 // content::NotificationObserver implementation.
50 virtual void Observe(int type,
51 const content::NotificationSource& source,
52 const content::NotificationDetails& details) OVERRIDE;
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(
61 int64 parent_frame_num,
63 const GURL& validated_url,
65 bool is_iframe_srcdoc,
66 content::RenderViewHost* render_view_host) OVERRIDE;
67 virtual void DidCommitProvisionalLoadForFrame(
69 const string16& frame_unique_name,
72 content::PageTransition transition_type,
73 content::RenderViewHost* render_view_host) OVERRIDE;
74 virtual void DidFailProvisionalLoad(
76 const string16& frame_unique_name,
78 const GURL& validated_url,
80 const string16& error_description,
81 content::RenderViewHost* render_view_host) OVERRIDE;
82 virtual void DocumentLoadedInFrame(
84 content::RenderViewHost* render_view_host) OVERRIDE;
85 virtual void DidFinishLoad(
87 const GURL& validated_url,
89 content::RenderViewHost* render_view_host) OVERRIDE;
90 virtual void DidFailLoad(
92 const GURL& validated_url,
95 const string16& error_description,
96 content::RenderViewHost* render_view_host) OVERRIDE;
97 virtual void DidOpenRequestedURL(content::WebContents* new_contents,
99 const content::Referrer& referrer,
100 WindowOpenDisposition disposition,
101 content::PageTransition transition,
102 int64 source_frame_num) OVERRIDE;
103 virtual void FrameDetached(content::RenderViewHost* render_view_host,
104 int64 frame_num) OVERRIDE;
105 virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
108 explicit WebNavigationTabObserver(content::WebContents* web_contents);
109 friend class content::WebContentsUserData<WebNavigationTabObserver>;
111 // True if the transition and target url correspond to a reference fragment
113 bool IsReferenceFragmentNavigation(FrameNavigationState::FrameID frame_id,
116 // Creates and sends onErrorOccurred events for all on-going navigations. If
117 // |render_view_host| is non-NULL, only generates events for frames in this
118 // render view host. If |id_to_skip| is given, no events are sent for that
120 void SendErrorEvents(content::WebContents* web_contents,
121 content::RenderViewHost* render_view_host,
122 FrameNavigationState::FrameID id_to_skip);
124 // Tracks the state of the frames we are sending events for.
125 FrameNavigationState navigation_state_;
127 // Used for tracking registrations to redirect notifications.
128 content::NotificationRegistrar registrar_;
130 // The current RenderViewHost of the observed WebContents.
131 content::RenderViewHost* render_view_host_;
133 // During a cross site navigation, the WebContents has a second, pending
135 content::RenderViewHost* pending_render_view_host_;
137 DISALLOW_COPY_AND_ASSIGN(WebNavigationTabObserver);
140 // Observes navigation notifications and routes them as events to the extension
142 class WebNavigationEventRouter : public TabStripModelObserver,
143 public chrome::BrowserListObserver,
144 public content::NotificationObserver {
146 explicit WebNavigationEventRouter(Profile* profile);
147 virtual ~WebNavigationEventRouter();
150 // Used to cache the information about newly created WebContents objects.
151 struct PendingWebContents{
152 PendingWebContents();
153 PendingWebContents(content::WebContents* source_web_contents,
154 int64 source_frame_id,
155 bool source_frame_is_main_frame,
156 content::WebContents* target_web_contents,
157 const GURL& target_url);
158 ~PendingWebContents();
160 content::WebContents* source_web_contents;
161 int64 source_frame_id;
162 bool source_frame_is_main_frame;
163 content::WebContents* target_web_contents;
167 // TabStripModelObserver implementation.
168 virtual void TabReplacedAt(TabStripModel* tab_strip_model,
169 content::WebContents* old_contents,
170 content::WebContents* new_contents,
173 // chrome::BrowserListObserver implementation.
174 virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
175 virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
177 // content::NotificationObserver implementation.
178 virtual void Observe(int type,
179 const content::NotificationSource& source,
180 const content::NotificationDetails& details) OVERRIDE;
182 // Handler for the NOTIFICATION_RETARGETING event. The method takes the
183 // details of such an event and stores them for the later
184 // NOTIFICATION_TAB_ADDED event.
185 void Retargeting(const RetargetingDetails* details);
187 // Handler for the NOTIFICATION_TAB_ADDED event. The method takes the details
188 // of such an event and creates a JSON formated extension event from it.
189 void TabAdded(content::WebContents* tab);
191 // Handler for NOTIFICATION_WEB_CONTENTS_DESTROYED. If |tab| is in
192 // |pending_web_contents_|, it is removed.
193 void TabDestroyed(content::WebContents* tab);
195 // Mapping pointers to WebContents objects to information about how they got
197 std::map<content::WebContents*, PendingWebContents> pending_web_contents_;
199 // Used for tracking registrations to navigation notifications.
200 content::NotificationRegistrar registrar_;
202 // The profile that owns us via ExtensionService.
205 DISALLOW_COPY_AND_ASSIGN(WebNavigationEventRouter);
208 // API function that returns the state of a given frame.
209 class WebNavigationGetFrameFunction : public ChromeSyncExtensionFunction {
210 virtual ~WebNavigationGetFrameFunction() {}
211 virtual bool RunImpl() OVERRIDE;
212 DECLARE_EXTENSION_FUNCTION("webNavigation.getFrame", WEBNAVIGATION_GETFRAME)
215 // API function that returns the states of all frames in a given tab.
216 class WebNavigationGetAllFramesFunction : public ChromeSyncExtensionFunction {
217 virtual ~WebNavigationGetAllFramesFunction() {}
218 virtual bool RunImpl() OVERRIDE;
219 DECLARE_EXTENSION_FUNCTION("webNavigation.getAllFrames",
220 WEBNAVIGATION_GETALLFRAMES)
223 class WebNavigationAPI : public ProfileKeyedAPI,
224 public extensions::EventRouter::Observer {
226 explicit WebNavigationAPI(Profile* profile);
227 virtual ~WebNavigationAPI();
229 // BrowserContextKeyedService implementation.
230 virtual void Shutdown() OVERRIDE;
232 // ProfileKeyedAPI implementation.
233 static ProfileKeyedAPIFactory<WebNavigationAPI>* GetFactoryInstance();
235 // EventRouter::Observer implementation.
236 virtual void OnListenerAdded(const extensions::EventListenerInfo& details)
240 friend class ProfileKeyedAPIFactory<WebNavigationAPI>;
244 // ProfileKeyedAPI implementation.
245 static const char* service_name() {
246 return "WebNavigationAPI";
248 static const bool kServiceIsNULLWhileTesting = true;
250 // Created lazily upon OnListenerAdded.
251 scoped_ptr<WebNavigationEventRouter> web_navigation_event_router_;
253 DISALLOW_COPY_AND_ASSIGN(WebNavigationAPI);
256 } // namespace extensions
258 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_NAVIGATION_WEB_NAVIGATION_API_H_