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 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