Index: chrome/browser/managed_mode/managed_mode_navigation_observer.cc |
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc |
index 2740d5fa5a0cea03ae196e436f0f77c315126949..3d96c3b3d23e94901f98be64c8f83bccf8263a74 100644 |
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc |
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc |
@@ -20,6 +20,7 @@ |
#include "chrome/browser/managed_mode/managed_user_service.h" |
#include "chrome/browser/managed_mode/managed_user_service_factory.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/tab_contents/tab_util.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_commands.h" |
#include "chrome/browser/ui/browser_finder.h" |
@@ -30,8 +31,12 @@ |
#include "chrome/common/pref_names.h" |
#include "chrome/common/url_constants.h" |
#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/notification_details.h" |
+#include "content/public/browser/notification_source.h" |
+#include "content/public/browser/notification_types.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
+#include "content/public/browser/resource_request_details.h" |
#include "content/public/browser/user_metrics.h" |
#include "content/public/browser/web_contents_delegate.h" |
#include "content/public/browser/web_contents_view.h" |
@@ -266,6 +271,7 @@ ManagedModeNavigationObserver::ManagedModeNavigationObserver( |
got_user_gesture_(false), |
state_(RECORDING_URLS_BEFORE_PREVIEW), |
is_elevated_(false), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
last_allowed_page_(-1) { |
Profile* profile = |
Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
@@ -273,6 +279,60 @@ ManagedModeNavigationObserver::ManagedModeNavigationObserver( |
if (!managed_user_service_->ProfileIsManaged()) |
is_elevated_ = true; |
url_filter_ = managed_user_service_->GetURLFilterForUIThread(); |
+ registrar_.Add(this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, |
+ content::Source<content::WebContents>(web_contents)); |
+} |
+ |
+// static |
+void ManagedModeNavigationObserver::DidBlockRequest( |
+ int render_process_id, |
+ int render_view_id, |
+ const GURL& url, |
+ const ManagedModeNavigationObserver::SuccessCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ // The tab might have been closed. |
+ content::WebContents* web_contents = |
+ tab_util::GetWebContentsByID(render_process_id, render_view_id); |
+ if (!web_contents) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, false)); |
+ return; |
+ } |
+ |
+ ManagedModeNavigationObserver* navigation_observer = |
+ ManagedModeNavigationObserver::FromWebContents(web_contents); |
+ if (!navigation_observer) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, false)); |
+ return; |
+ } |
+ navigation_observer->AddInterstitialCallback(url, callback); |
+} |
+ |
+void ManagedModeNavigationObserver::ShowInterstitial(const GURL& url) { |
+ // If we already have callbacks queued up, we don't need to show the |
+ // interstitial again. |
+ if (!callbacks_.empty()) |
+ return; |
+ |
+ new ManagedModeInterstitial( |
+ web_contents(), url, |
+ base::Bind(&ManagedModeNavigationObserver::OnInterstitialResult, |
+ weak_ptr_factory_.GetWeakPtr())); |
+} |
+ |
+void ManagedModeNavigationObserver::AddInterstitialCallback( |
+ const GURL& url, |
+ const ManagedModeNavigationObserver::SuccessCallback& callback) { |
+ if (state_ == RECORDING_URLS_AFTER_PREVIEW) { |
+ // Return immediately if we are in preview mode. |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, true)); |
+ return; |
+ } |
+ |
+ ShowInterstitial(url); |
+ callbacks_.push_back(callback); |
} |
void ManagedModeNavigationObserver::AddTemporaryException() { |
@@ -332,12 +392,12 @@ void ManagedModeNavigationObserver::AddSavedURLsToWhitelistAndClearState() { |
for (std::set<GURL>::const_iterator it = navigated_urls_.begin(); |
it != navigated_urls_.end(); |
++it) { |
- if (it->host() != last_url_.host()) |
+ if (!CanTemporarilyNavigateHost(*it)) |
urls.push_back(*it); |
} |
managed_user_service_->SetManualBehaviorForURLs( |
urls, ManagedUserService::MANUAL_ALLOW); |
- if (last_url_.is_valid()) { |
+ if (!last_url_.is_empty()) { |
std::vector<std::string> hosts; |
hosts.push_back(last_url_.host()); |
managed_user_service_->SetManualBehaviorForHosts( |
@@ -359,10 +419,6 @@ void ManagedModeNavigationObserver::AddURLToPatternList(const GURL& url) { |
last_url_ = url; |
} |
-void ManagedModeNavigationObserver::SetStateToRecordingAfterPreview() { |
- state_ = RECORDING_URLS_AFTER_PREVIEW; |
-} |
- |
bool ManagedModeNavigationObserver::CanTemporarilyNavigateHost( |
const GURL& url) { |
return last_url_.host() == url.host(); |
@@ -400,6 +456,19 @@ void ManagedModeNavigationObserver::ClearObserverState() { |
RemoveTemporaryException(); |
} |
+void ManagedModeNavigationObserver::OnInterstitialResult(bool result) { |
+ DCHECK_EQ(RECORDING_URLS_BEFORE_PREVIEW, state_); |
+ if (result) |
+ state_ = RECORDING_URLS_AFTER_PREVIEW; |
+ |
+ for (std::vector<SuccessCallback>::const_iterator it = callbacks_.begin(); |
+ it != callbacks_.end(); ++it) { |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(*it, result)); |
+ } |
+ callbacks_.clear(); |
+} |
+ |
void ManagedModeNavigationObserver::NavigateToPendingEntry( |
const GURL& url, |
content::NavigationController::ReloadType reload_type) { |
@@ -414,78 +483,25 @@ void ManagedModeNavigationObserver::NavigateToPendingEntry( |
} |
} |
-void ManagedModeNavigationObserver::DidNavigateMainFrame( |
- const content::LoadCommittedDetails& details, |
- const content::FrameNavigateParams& params) { |
- if (!ShouldStayElevatedForURL(params.url)) |
- is_elevated_ = false; |
- |
- content::RecordAction(UserMetricsAction("ManagedMode_MainFrameNavigation")); |
- |
- ManagedModeURLFilter::FilteringBehavior behavior = |
- url_filter_->GetFilteringBehaviorForURL(params.url); |
- |
- UMA_HISTOGRAM_ENUMERATION("ManagedMode.FilteringBehavior", |
- behavior, |
- ManagedModeURLFilter::HISTOGRAM_BOUNDING_VALUE); |
- |
- // The page can be redirected to a different domain, record those URLs as |
- // well. |
- if (behavior == ManagedModeURLFilter::BLOCK && |
- !CanTemporarilyNavigateHost(params.url)) |
- AddURLToPatternList(params.url); |
- |
- if (behavior == ManagedModeURLFilter::ALLOW && |
- state_ == RECORDING_URLS_AFTER_PREVIEW) { |
- // The initial page that triggered the interstitial was blocked but the |
- // final page is already in the whitelist so add the series of URLs |
- // which lead to the final page to the whitelist as well. |
- // Update the |last_url_| since it was not added to the list before. |
- last_url_ = params.url; |
- AddSavedURLsToWhitelistAndClearState(); |
- SimpleAlertInfoBarDelegate::Create( |
- InfoBarService::FromWebContents(web_contents()), |
- NULL, |
- l10n_util::GetStringUTF16(IDS_MANAGED_MODE_ALREADY_ADDED_MESSAGE), |
- true); |
- return; |
- } |
- |
- // Update the exception to the last host visited. A redirect can follow this |
- // so don't update the state yet. |
- if (state_ == RECORDING_URLS_AFTER_PREVIEW) { |
- AddTemporaryException(); |
- } |
- |
- // The navigation is complete, unless there is a redirect. So set the |
- // new navigation to false to detect user interaction. |
- got_user_gesture_ = false; |
-} |
- |
void ManagedModeNavigationObserver::ProvisionalChangeToMainFrameUrl( |
const GURL& url, |
content::RenderViewHost* render_view_host) { |
if (!ShouldStayElevatedForURL(url)) |
is_elevated_ = false; |
- // This function is the last one to be called before the resource throttle |
- // shows the interstitial if the URL must be blocked. |
- DVLOG(1) << "ProvisionalChangeToMainFrameURL " << url.spec(); |
ManagedModeURLFilter::FilteringBehavior behavior = |
url_filter_->GetFilteringBehaviorForURL(url); |
- |
if (behavior != ManagedModeURLFilter::BLOCK) |
return; |
- if (state_ == RECORDING_URLS_AFTER_PREVIEW && got_user_gesture_ && |
- !CanTemporarilyNavigateHost(url)) |
- ClearObserverState(); |
- |
- if (behavior == ManagedModeURLFilter::BLOCK && |
- !CanTemporarilyNavigateHost(url)) |
- AddURLToPatternList(url); |
+ if (state_ == RECORDING_URLS_BEFORE_PREVIEW) { |
+ ShowInterstitial(url); |
+ } else { |
+ if (got_user_gesture_ && !CanTemporarilyNavigateHost(url)) |
+ ClearObserverState(); |
- got_user_gesture_ = false; |
+ got_user_gesture_ = false; |
+ } |
} |
void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame( |
@@ -528,9 +544,72 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame( |
last_allowed_page_ = web_contents()->GetController().GetCurrentEntryIndex(); |
} |
+void ManagedModeNavigationObserver::DidNavigateMainFrame( |
+ const content::LoadCommittedDetails& details, |
+ const content::FrameNavigateParams& params) { |
+ if (!ShouldStayElevatedForURL(params.url)) |
+ is_elevated_ = false; |
+ |
+ content::RecordAction(UserMetricsAction("ManagedMode_MainFrameNavigation")); |
+ |
+ ManagedModeURLFilter::FilteringBehavior behavior = |
+ url_filter_->GetFilteringBehaviorForURL(params.url); |
+ |
+ UMA_HISTOGRAM_ENUMERATION("ManagedMode.FilteringBehavior", |
+ behavior, |
+ ManagedModeURLFilter::HISTOGRAM_BOUNDING_VALUE); |
+ |
+ // The page can be redirected to a different domain, record those URLs as |
+ // well. |
+ if (behavior == ManagedModeURLFilter::BLOCK && |
+ !CanTemporarilyNavigateHost(params.url)) |
+ AddURLToPatternList(params.url); |
+ |
+ if (behavior == ManagedModeURLFilter::ALLOW && |
+ state_ == RECORDING_URLS_AFTER_PREVIEW) { |
+ // The initial page that triggered the interstitial was blocked but the |
+ // final page is already in the whitelist so add the series of URLs |
+ // which lead to the final page to the whitelist as well. |
+ // Update the |last_url_| since it was not added to the list before. |
+ last_url_ = params.url; |
+ AddSavedURLsToWhitelistAndClearState(); |
+ SimpleAlertInfoBarDelegate::Create( |
+ InfoBarService::FromWebContents(web_contents()), |
+ NULL, |
+ l10n_util::GetStringUTF16(IDS_MANAGED_MODE_ALREADY_ADDED_MESSAGE), |
+ true); |
+ return; |
+ } |
+ |
+ // Update the exception to the last host visited. A redirect can follow this |
+ // so don't update the state yet. |
+ if (state_ == RECORDING_URLS_AFTER_PREVIEW) |
+ AddTemporaryException(); |
+ |
+ // The navigation is complete, unless there is a redirect. So set the |
+ // new navigation to false to detect user interaction. |
+ got_user_gesture_ = false; |
+} |
+ |
void ManagedModeNavigationObserver::DidGetUserGesture() { |
got_user_gesture_ = true; |
// Update the exception status so that the resource throttle knows that |
// there was a manual navigation. |
UpdateExceptionNavigationStatus(); |
} |
+ |
+void ManagedModeNavigationObserver::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ DCHECK_EQ(content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, type); |
+ const GURL& url = |
+ content::Details<content::ResourceRedirectDetails>(details)->url; |
+ ManagedModeURLFilter::FilteringBehavior behavior = |
+ url_filter_->GetFilteringBehaviorForURL(url); |
+ if (behavior == ManagedModeURLFilter::BLOCK && |
+ state_ == RECORDING_URLS_AFTER_PREVIEW && |
+ !CanTemporarilyNavigateHost(url)) { |
+ AddURLToPatternList(url); |
+ } |
+} |