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