// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Defines the Chrome Extensions WebNavigation API functions for observing and // intercepting navigation events, as specified in // chrome/common/extensions/api/extension_api.json. #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_ #pragma once #include <map> #include "base/memory/singleton.h" #include "chrome/browser/extensions/extension_function.h" #include "content/browser/tab_contents/tab_contents_observer.h" #include "content/common/notification_observer.h" #include "content/common/notification_registrar.h" #include "googleurl/src/gurl.h" class TabContents; struct ViewHostMsg_CreateWindow_Params; // Tracks the navigation state of all frames currently known to the // webNavigation API. It is mainly used to track in which frames an error // occurred so no further events for this frame are being sent. class FrameNavigationState { public: FrameNavigationState(); ~FrameNavigationState(); // True if navigation events for the given frame can be sent. bool CanSendEvents(int64 frame_id) const; // Starts to track a frame given by its |frame_id| showing the URL |url| in // a |tab_contents|. void TrackFrame(int64 frame_id, const GURL& url, bool is_main_frame, bool is_error_page, const TabContents* tab_contents); // Returns the URL corresponding to a tracked frame given by its |frame_id|. GURL GetUrl(int64 frame_id) const; // True if the frame given by its |frame_id| is the main frame of its tab. bool IsMainFrame(int64 frame_id) const; // Marks a frame as in an error state. void ErrorOccurredInFrame(int64 frame_id); // Removes state associated with this tab contents and all of its frames. void RemoveTabContentsState(const TabContents* tab_contents); #ifdef UNIT_TEST static void set_allow_extension_scheme(bool allow_extension_scheme) { allow_extension_scheme_ = allow_extension_scheme; } #endif private: typedef std::multimap<const TabContents*, int64> TabContentsToFrameIdMap; struct FrameState { bool error_occurred; // True if an error has occurred in this frame. bool is_main_frame; // True if this is a main frame. GURL url; // URL of this frame. }; typedef std::map<int64, FrameState> FrameIdToStateMap; // Tracks which frames belong to a given tab contents object. TabContentsToFrameIdMap tab_contents_map_; // Tracks the state of known frames. FrameIdToStateMap frame_state_map_; // If true, also allow events from chrome-extension:// URLs. static bool allow_extension_scheme_; DISALLOW_COPY_AND_ASSIGN(FrameNavigationState); }; // Tab contents observer that forwards navigation events to the event router. class ExtensionWebNavigationTabObserver : public TabContentsObserver { public: explicit ExtensionWebNavigationTabObserver(TabContents* tab_contents); virtual ~ExtensionWebNavigationTabObserver(); // TabContentsObserver implementation. virtual void DidStartProvisionalLoadForFrame(int64 frame_id, bool is_main_frame, const GURL& validated_url, bool is_error_page) OVERRIDE; virtual void DidCommitProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, const GURL& url, PageTransition::Type transition_type) OVERRIDE; virtual void DidFailProvisionalLoad(int64 frame_id, bool is_main_frame, const GURL& validated_url, int error_code) OVERRIDE; virtual void DocumentLoadedInFrame(int64 frame_id) OVERRIDE; virtual void DidFinishLoad(int64 frame_id) OVERRIDE; virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE; virtual void DidOpenURL(const GURL& url, const GURL& referrer, WindowOpenDisposition disposition, PageTransition::Type transition); private: // True if the transition and target url correspond to a reference fragment // navigation. bool IsReferenceFragmentNavigation(int64 frame_id, const GURL& url); // Simulates a complete series of events for reference fragment navigations. void NavigatedReferenceFragment(int64 frame_id, bool is_main_frame, const GURL& url, PageTransition::Type transition_type); // Tracks the state of the frames we are sending events for. FrameNavigationState navigation_state_; DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationTabObserver); }; // Observes navigation notifications and routes them as events to the extension // system. class ExtensionWebNavigationEventRouter : public NotificationObserver { public: // Returns the singleton instance of the event router. static ExtensionWebNavigationEventRouter* GetInstance(); // Invoked by the extensions service once the extension system is fully set // up and can start dispatching events to extensions. void Init(); private: friend struct DefaultSingletonTraits<ExtensionWebNavigationEventRouter>; ExtensionWebNavigationEventRouter(); virtual ~ExtensionWebNavigationEventRouter(); // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); // Handler for the CREATING_NEW_WINDOW event. The method takes the details of // such an event and constructs a suitable JSON formatted extension event from // it. void CreatingNewWindow(TabContents* tab_content, const ViewHostMsg_CreateWindow_Params* details); // Used for tracking registrations to navigation notifications. NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(ExtensionWebNavigationEventRouter); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBNAVIGATION_API_H_