// Copyright (c) 2012 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. #ifndef CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_ #define CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_ #include #include "base/values.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" class InfoBarDelegate; class ManagedModeURLFilter; class ManagedUserService; class ManagedModeNavigationObserver : public content::WebContentsObserver, public content::WebContentsUserData { public: virtual ~ManagedModeNavigationObserver(); // Sets the specific infobar as dismissed. void WarnInfobarDismissed(); void PreviewInfobarDismissed(); // Sets the state of the Observer from the outside. void SetStateToRecordingAfterPreview(); // Returns whether the user should be allowed to navigate to this URL after // he has clicked "Preview" on the interstitial. bool CanTemporarilyNavigateHost(const GURL& url); // Clears the state recorded in the observer. void ClearObserverState(); // Whitelists exact URLs for redirects and host patterns for the final URL. // If the URL uses HTTPS, whitelists only the host on HTTPS. Clears the // observer state after adding the URLs. void AddSavedURLsToWhitelistAndClearState(); // Returns the elevation state for the corresponding WebContents. bool is_elevated() const; // Set the elevation state for the corresponding WebContents. void set_elevated(bool is_elevated); // Adds a special history entry for the visit attempt and shows the // interstitial. static void OnRequestBlocked(int render_process_host_id, int render_view_id, const GURL& url, const base::Callback& callback); private: // An observer can be in one of the following states: // - RECORDING_URLS_BEFORE_PREVIEW: This is the initial state when the user // navigates to a new page. In this state the navigated URLs that should be // blocked are recorded. The Observer moves to the next state when an // interstitial was shown and the user clicked "Preview" on the interstitial. // - RECORDING_URLS_AFTER_PREVIEW: URLs that should be blocked are // still recorded while the page redirects. The Observer moves to the next // state after the page finished redirecting (DidNavigateMainFrame gets // called). enum ObserverState { RECORDING_URLS_BEFORE_PREVIEW, RECORDING_URLS_AFTER_PREVIEW, }; friend class content::WebContentsUserData; explicit ManagedModeNavigationObserver(content::WebContents* web_contents); // Adding the temporary exception stops the ResourceThrottle from showing // an interstitial for this RenderView. This allows the user to navigate // around on the website after clicking preview. void AddTemporaryException(); void RemoveTemporaryException(); void AddURLToPatternList(const GURL& url); // content::WebContentsObserver implementation. // An example regarding the order in which these events take place for // google.com in our case is as follows: // 1. User types in google.com and clicks enter. // -> NavigateToPendingEntry: http://google.com // -> DidStartProvisionalLoadForFrame http://google.com // -> ProvisionalChangeToMainFrameUrl http://google.com // 2. Interstitial is shown to the user. User clicks "Preview". // -> ProvisionalChangeToMainFrameUrl http://www.google.com (redirect) // -> DidCommitProvisionalLoadForFrame http://www.google.com (redirect) // -> DidNavigateMainFrame http://www.google.com // 3. Page is shown. virtual void NavigateToPendingEntry( const GURL& url, content::NavigationController::ReloadType reload_type) OVERRIDE; virtual void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) OVERRIDE; virtual void ProvisionalChangeToMainFrameUrl( const GURL& url, content::RenderViewHost* render_view_host) OVERRIDE; virtual void DidCommitProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, const GURL& url, content::PageTransition transition_type, content::RenderViewHost* render_view_host) OVERRIDE; // Returns whether the user would stay in elevated state if he visits this // URL. bool ShouldStayElevatedForURL(const GURL& url); // Owned by the profile, so outlives us. ManagedUserService* managed_user_service_; // Owned by ManagedUserService. const ManagedModeURLFilter* url_filter_; // Owned by the InfoBarService, which has the same lifetime as this object. InfoBarDelegate* warn_infobar_delegate_; InfoBarDelegate* preview_infobar_delegate_; ObserverState state_; std::set navigated_urls_; GURL last_url_; // The elevation state corresponding to the current WebContents. // Will be set to true for non-managed users. bool is_elevated_; int last_allowed_page_; // There are two starting points for a new navigation: // 1. NavigateToPendingEntry when the omnibox is used to navigate to a URL or // the user goes back or forward. // 2. ProvisionalChangeToMainFrameURL when the user clicks on a link. // The main problem is that ProvisionalChangeToMainFrameURL is called for // redirects as well and we need a way to distinguish between the two // scenarios. |finished_redirects_| helps us do that by tracking the cases // when the user did not click on a URL. bool finished_redirects_; DISALLOW_COPY_AND_ASSIGN(ManagedModeNavigationObserver); }; #endif // CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_