| OLD | NEW |
| (Empty) |
| 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_EXTENSION_WEBNAVIGATION_API_H_ | |
| 9 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_ | |
| 10 #pragma once | |
| 11 | |
| 12 #include <map> | |
| 13 #include <set> | |
| 14 | |
| 15 #include "base/compiler_specific.h" | |
| 16 #include "chrome/browser/extensions/extension_function.h" | |
| 17 #include "chrome/browser/profiles/profile.h" | |
| 18 #include "content/public/browser/notification_observer.h" | |
| 19 #include "content/public/browser/notification_registrar.h" | |
| 20 #include "content/public/browser/web_contents_observer.h" | |
| 21 #include "googleurl/src/gurl.h" | |
| 22 | |
| 23 struct RetargetingDetails; | |
| 24 | |
| 25 // Tracks the navigation state of all frames in a given tab currently known to | |
| 26 // the 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 typedef std::set<int64>::const_iterator const_iterator; | |
| 31 | |
| 32 FrameNavigationState(); | |
| 33 ~FrameNavigationState(); | |
| 34 | |
| 35 // Use these to iterate over all frame IDs known by this object. | |
| 36 const_iterator begin() const { return frame_ids_.begin(); } | |
| 37 const_iterator end() const { return frame_ids_.end(); } | |
| 38 | |
| 39 // True if navigation events for the given frame can be sent. | |
| 40 bool CanSendEvents(int64 frame_id) const; | |
| 41 | |
| 42 // True if in general webNavigation events may be sent for the given URL. | |
| 43 bool IsValidUrl(const GURL& url) const; | |
| 44 | |
| 45 // Starts to track a frame identified by its |frame_id| showing the URL |url|. | |
| 46 void TrackFrame(int64 frame_id, | |
| 47 const GURL& url, | |
| 48 bool is_main_frame, | |
| 49 bool is_error_page); | |
| 50 | |
| 51 // Update the URL associated with a given frame. | |
| 52 void UpdateFrame(int64 frame_id, const GURL& url); | |
| 53 | |
| 54 // Returns true if |frame_id| is a known frame. | |
| 55 bool IsValidFrame(int64 frame_id) const; | |
| 56 | |
| 57 // Returns the URL corresponding to a tracked frame given by its |frame_id|. | |
| 58 GURL GetUrl(int64 frame_id) const; | |
| 59 | |
| 60 // True if the frame given by its |frame_id| is the main frame of its tab. | |
| 61 bool IsMainFrame(int64 frame_id) const; | |
| 62 | |
| 63 // Returns the frame ID of the main frame, or -1 if the frame ID is not | |
| 64 // known. | |
| 65 int64 GetMainFrameID() const; | |
| 66 | |
| 67 // Marks a frame as in an error state, i.e. the onErrorOccurred event was | |
| 68 // fired for this frame, and no further events should be sent for it. | |
| 69 void SetErrorOccurredInFrame(int64 frame_id); | |
| 70 | |
| 71 // True if the frame is marked as being in an error state. | |
| 72 bool GetErrorOccurredInFrame(int64 frame_id) const; | |
| 73 | |
| 74 // Marks a frame as having finished its last navigation, i.e. the onCompleted | |
| 75 // event was fired for this frame. | |
| 76 void SetNavigationCompleted(int64 frame_id); | |
| 77 | |
| 78 // True if the frame is currently not navigating. | |
| 79 bool GetNavigationCompleted(int64 frame_id) const; | |
| 80 | |
| 81 // Marks a frame as having committed its navigation, i.e. the onCommitted | |
| 82 // event was fired for this frame. | |
| 83 void SetNavigationCommitted(int64 frame_id); | |
| 84 | |
| 85 // True if the frame has committed its navigation. | |
| 86 bool GetNavigationCommitted(int64 frame_id) const; | |
| 87 | |
| 88 // Marks a frame as redirected by the server. | |
| 89 void SetIsServerRedirected(int64 frame_id); | |
| 90 | |
| 91 // True if the frame was redirected by the server. | |
| 92 bool GetIsServerRedirected(int64 frame_id) const; | |
| 93 | |
| 94 #ifdef UNIT_TEST | |
| 95 static void set_allow_extension_scheme(bool allow_extension_scheme) { | |
| 96 allow_extension_scheme_ = allow_extension_scheme; | |
| 97 } | |
| 98 #endif | |
| 99 | |
| 100 private: | |
| 101 struct FrameState { | |
| 102 bool error_occurred; // True if an error has occurred in this frame. | |
| 103 bool is_main_frame; // True if this is a main frame. | |
| 104 bool is_navigating; // True if there is a navigation going on. | |
| 105 bool is_committed; // True if the navigation is already committed. | |
| 106 bool is_server_redirected; // True if a server redirect happened. | |
| 107 GURL url; // URL of this frame. | |
| 108 }; | |
| 109 typedef std::map<int64, FrameState> FrameIdToStateMap; | |
| 110 | |
| 111 // Tracks the state of known frames. | |
| 112 FrameIdToStateMap frame_state_map_; | |
| 113 | |
| 114 // Set of all known frames. | |
| 115 std::set<int64> frame_ids_; | |
| 116 | |
| 117 // The current main frame. | |
| 118 int64 main_frame_id_; | |
| 119 | |
| 120 // If true, also allow events from chrome-extension:// URLs. | |
| 121 static bool allow_extension_scheme_; | |
| 122 | |
| 123 DISALLOW_COPY_AND_ASSIGN(FrameNavigationState); | |
| 124 }; | |
| 125 | |
| 126 // Tab contents observer that forwards navigation events to the event router. | |
| 127 class ExtensionWebNavigationTabObserver : public content::NotificationObserver, | |
| 128 public content::WebContentsObserver { | |
| 129 public: | |
| 130 explicit ExtensionWebNavigationTabObserver( | |
| 131 content::WebContents* web_contents); | |
| 132 virtual ~ExtensionWebNavigationTabObserver(); | |
| 133 | |
| 134 // Returns the object for the given |tab_contents|. | |
| 135 static ExtensionWebNavigationTabObserver* Get( | |
| 136 content::WebContents* web_contents); | |
| 137 | |
| 138 const FrameNavigationState& frame_navigation_state() const { | |
| 139 return navigation_state_; | |
| 140 } | |
| 141 | |
| 142 // content::NotificationObserver implementation. | |
| 143 virtual void Observe(int type, | |
| 144 const content::NotificationSource& source, | |
| 145 const content::NotificationDetails& details) OVERRIDE; | |
| 146 | |
| 147 | |
| 148 // content::WebContentsObserver implementation. | |
| 149 virtual void DidStartProvisionalLoadForFrame( | |
| 150 int64 frame_id, | |
| 151 bool is_main_frame, | |
| 152 const GURL& validated_url, | |
| 153 bool is_error_page, | |
| 154 content::RenderViewHost* render_view_host) OVERRIDE; | |
| 155 virtual void DidCommitProvisionalLoadForFrame( | |
| 156 int64 frame_id, | |
| 157 bool is_main_frame, | |
| 158 const GURL& url, | |
| 159 content::PageTransition transition_type) OVERRIDE; | |
| 160 virtual void DidFailProvisionalLoad( | |
| 161 int64 frame_id, | |
| 162 bool is_main_frame, | |
| 163 const GURL& validated_url, | |
| 164 int error_code, | |
| 165 const string16& error_description) OVERRIDE; | |
| 166 virtual void DocumentLoadedInFrame(int64 frame_id) OVERRIDE; | |
| 167 virtual void DidFinishLoad(int64 frame_id, | |
| 168 const GURL& validated_url, | |
| 169 bool is_main_frame) OVERRIDE; | |
| 170 virtual void DidOpenRequestedURL(content::WebContents* new_contents, | |
| 171 const GURL& url, | |
| 172 const content::Referrer& referrer, | |
| 173 WindowOpenDisposition disposition, | |
| 174 content::PageTransition transition, | |
| 175 int64 source_frame_id) OVERRIDE; | |
| 176 virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE; | |
| 177 | |
| 178 private: | |
| 179 // True if the transition and target url correspond to a reference fragment | |
| 180 // navigation. | |
| 181 bool IsReferenceFragmentNavigation(int64 frame_id, const GURL& url); | |
| 182 | |
| 183 // Tracks the state of the frames we are sending events for. | |
| 184 FrameNavigationState navigation_state_; | |
| 185 | |
| 186 // Used for tracking registrations to redirect notifications. | |
| 187 content::NotificationRegistrar registrar_; | |
| 188 | |
| 189 DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationTabObserver); | |
| 190 }; | |
| 191 | |
| 192 // Observes navigation notifications and routes them as events to the extension | |
| 193 // system. | |
| 194 class ExtensionWebNavigationEventRouter : public content::NotificationObserver { | |
| 195 public: | |
| 196 explicit ExtensionWebNavigationEventRouter(Profile* profile); | |
| 197 virtual ~ExtensionWebNavigationEventRouter(); | |
| 198 | |
| 199 // Invoked by the extensions service once the extension system is fully set | |
| 200 // up and can start dispatching events to extensions. | |
| 201 void Init(); | |
| 202 | |
| 203 private: | |
| 204 // Used to cache the information about newly created WebContents objects. | |
| 205 struct PendingWebContents{ | |
| 206 PendingWebContents(); | |
| 207 PendingWebContents(content::WebContents* source_web_contents, | |
| 208 int64 source_frame_id, | |
| 209 bool source_frame_is_main_frame, | |
| 210 content::WebContents* target_web_contents, | |
| 211 const GURL& target_url); | |
| 212 ~PendingWebContents(); | |
| 213 | |
| 214 content::WebContents* source_web_contents; | |
| 215 int64 source_frame_id; | |
| 216 bool source_frame_is_main_frame; | |
| 217 content::WebContents* target_web_contents; | |
| 218 GURL target_url; | |
| 219 }; | |
| 220 | |
| 221 // content::NotificationObserver implementation. | |
| 222 virtual void Observe(int type, | |
| 223 const content::NotificationSource& source, | |
| 224 const content::NotificationDetails& details) OVERRIDE; | |
| 225 | |
| 226 // Handler for the NOTIFICATION_RETARGETING event. The method takes the | |
| 227 // details of such an event and stores them for the later | |
| 228 // NOTIFICATION_TAB_ADDED event. | |
| 229 void Retargeting(const RetargetingDetails* details); | |
| 230 | |
| 231 // Handler for the NOTIFICATION_TAB_ADDED event. The method takes the details | |
| 232 // of such an event and creates a JSON formated extension event from it. | |
| 233 void TabAdded(content::WebContents* tab); | |
| 234 | |
| 235 // Handler for NOTIFICATION_WEB_CONTENTS_DESTROYED. If |tab| is in | |
| 236 // |pending_web_contents_|, it is removed. | |
| 237 void TabDestroyed(content::WebContents* tab); | |
| 238 | |
| 239 // Mapping pointers to WebContents objects to information about how they got | |
| 240 // created. | |
| 241 std::map<content::WebContents*, PendingWebContents> pending_web_contents_; | |
| 242 | |
| 243 // Used for tracking registrations to navigation notifications. | |
| 244 content::NotificationRegistrar registrar_; | |
| 245 | |
| 246 // The profile that owns us via ExtensionService. | |
| 247 Profile* profile_; | |
| 248 | |
| 249 DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationEventRouter); | |
| 250 }; | |
| 251 | |
| 252 // API function that returns the state of a given frame. | |
| 253 class GetFrameFunction : public SyncExtensionFunction { | |
| 254 virtual ~GetFrameFunction() {} | |
| 255 virtual bool RunImpl() OVERRIDE; | |
| 256 DECLARE_EXTENSION_FUNCTION_NAME("webNavigation.getFrame") | |
| 257 }; | |
| 258 | |
| 259 // API function that returns the states of all frames in a given tab. | |
| 260 class GetAllFramesFunction : public SyncExtensionFunction { | |
| 261 virtual ~GetAllFramesFunction() {} | |
| 262 virtual bool RunImpl() OVERRIDE; | |
| 263 DECLARE_EXTENSION_FUNCTION_NAME("webNavigation.getAllFrames") | |
| 264 }; | |
| 265 | |
| 266 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_ | |
| OLD | NEW |