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