| 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 945802e00775bd7d86f96329b65f083ec592234f..eb844b37610202d8014dff5727c36b12cf618787 100644
|
| --- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
|
| +++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
|
| @@ -4,25 +4,43 @@
|
|
|
| #include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
|
|
|
| +#include "base/bind.h"
|
| +#include "base/i18n/rtl.h"
|
| +#include "base/string_number_conversions.h"
|
| #include "chrome/browser/api/infobars/confirm_infobar_delegate.h"
|
| #include "chrome/browser/api/infobars/infobar_service.h"
|
| +#include "chrome/browser/api/infobars/simple_alert_infobar_delegate.h"
|
| #include "chrome/browser/managed_mode/managed_mode.h"
|
| +#include "chrome/browser/managed_mode/managed_mode_interstitial.h"
|
| +#include "chrome/browser/managed_mode/managed_mode_resource_throttle.h"
|
| #include "chrome/browser/managed_mode/managed_mode_url_filter.h"
|
| +#include "chrome/browser/prefs/pref_service.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/browser_finder.h"
|
| #include "chrome/browser/ui/browser_list.h"
|
| +#include "chrome/common/jstemplate_builder.h"
|
| +#include "chrome/common/pref_names.h"
|
| #include "chrome/common/url_constants.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/render_view_host.h"
|
| #include "content/public/browser/web_contents_delegate.h"
|
| #include "content/public/common/frame_navigate_params.h"
|
| #include "grit/generated_resources.h"
|
| +#include "grit/locale_settings.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
|
|
| +using content::BrowserThread;
|
| +
|
| namespace {
|
|
|
| class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
|
| public:
|
| - explicit ManagedModeWarningInfobarDelegate(InfoBarService* infobar_service);
|
| + explicit ManagedModeWarningInfobarDelegate(
|
| + InfoBarService* infobar_service,
|
| + int last_allowed_page);
|
|
|
| private:
|
| virtual ~ManagedModeWarningInfobarDelegate();
|
| @@ -39,6 +57,8 @@ class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
|
| const content::LoadCommittedDetails& details) const OVERRIDE;
|
| virtual void InfoBarDismissed() OVERRIDE;
|
|
|
| + int last_allowed_page_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfobarDelegate);
|
| };
|
|
|
| @@ -65,8 +85,10 @@ void GoBackToSafety(content::WebContents* web_contents) {
|
| }
|
|
|
| ManagedModeWarningInfobarDelegate::ManagedModeWarningInfobarDelegate(
|
| - InfoBarService* infobar_service)
|
| - : ConfirmInfoBarDelegate(infobar_service) {}
|
| + InfoBarService* infobar_service,
|
| + int last_allowed_page)
|
| + : ConfirmInfoBarDelegate(infobar_service),
|
| + last_allowed_page_(last_allowed_page) {}
|
|
|
| ManagedModeWarningInfobarDelegate::~ManagedModeWarningInfobarDelegate() {}
|
|
|
| @@ -107,23 +129,270 @@ void ManagedModeWarningInfobarDelegate::InfoBarDismissed() {
|
| observer->WarnInfobarDismissed();
|
| }
|
|
|
| +class ManagedModePreviewInfobarDelegate : public ConfirmInfoBarDelegate {
|
| + public:
|
| + explicit ManagedModePreviewInfobarDelegate(
|
| + InfoBarService* infobar_service);
|
| +
|
| + private:
|
| + virtual ~ManagedModePreviewInfobarDelegate();
|
| +
|
| + // ConfirmInfoBarDelegate overrides:
|
| + virtual string16 GetMessageText() const OVERRIDE;
|
| + virtual int GetButtons() const OVERRIDE;
|
| + virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
|
| + virtual bool Accept() OVERRIDE;
|
| + virtual bool Cancel() OVERRIDE;
|
| +
|
| + // InfoBarDelegate override:
|
| + virtual bool ShouldExpire(
|
| + const content::LoadCommittedDetails& details) const OVERRIDE;
|
| + virtual void InfoBarDismissed() OVERRIDE;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ManagedModePreviewInfobarDelegate);
|
| +};
|
| +
|
| +ManagedModePreviewInfobarDelegate::ManagedModePreviewInfobarDelegate(
|
| + InfoBarService* infobar_service)
|
| + : ConfirmInfoBarDelegate(infobar_service) {}
|
| +
|
| +ManagedModePreviewInfobarDelegate::~ManagedModePreviewInfobarDelegate() {}
|
| +
|
| +string16 ManagedModePreviewInfobarDelegate::GetMessageText() const {
|
| + return l10n_util::GetStringUTF16(IDS_MANAGED_MODE_PREVIEW_MESSAGE);
|
| +}
|
| +
|
| +int ManagedModePreviewInfobarDelegate::GetButtons() const {
|
| + return BUTTON_OK | BUTTON_CANCEL;
|
| +}
|
| +
|
| +string16 ManagedModePreviewInfobarDelegate::GetButtonLabel(
|
| + InfoBarButton button) const {
|
| + return l10n_util::GetStringUTF16(
|
| + (button == BUTTON_OK) ? IDS_MANAGED_MODE_PREVIEW_ACCEPT
|
| + : IDS_MANAGED_MODE_GO_BACK_ACTION);
|
| +}
|
| +
|
| +bool ManagedModePreviewInfobarDelegate::Accept() {
|
| + ManagedModeNavigationObserver* observer =
|
| + ManagedModeNavigationObserver::FromWebContents(
|
| + owner()->GetWebContents());
|
| + observer->AddSavedURLsToWhitelistAndClearState();
|
| + return true;
|
| +}
|
| +
|
| +bool ManagedModePreviewInfobarDelegate::Cancel() {
|
| + GoBackToSafety(owner()->GetWebContents());
|
| + return false;
|
| +}
|
| +
|
| +bool ManagedModePreviewInfobarDelegate::ShouldExpire(
|
| + const content::LoadCommittedDetails& details) const {
|
| + // ManagedModeNavigationObserver removes us below.
|
| + return false;
|
| +}
|
| +
|
| +void ManagedModePreviewInfobarDelegate::InfoBarDismissed() {
|
| + ManagedModeNavigationObserver* observer =
|
| + ManagedModeNavigationObserver::FromWebContents(
|
| + owner()->GetWebContents());
|
| + observer->PreviewInfobarDismissed();
|
| +}
|
| +
|
| } // namespace
|
|
|
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagedModeNavigationObserver)
|
|
|
| -ManagedModeNavigationObserver::~ManagedModeNavigationObserver() {}
|
| +ManagedModeNavigationObserver::~ManagedModeNavigationObserver() {
|
| + RemoveTemporaryException();
|
| +}
|
|
|
| ManagedModeNavigationObserver::ManagedModeNavigationObserver(
|
| content::WebContents* web_contents)
|
| : WebContentsObserver(web_contents),
|
| url_filter_(ManagedMode::GetURLFilterForUIThread()),
|
| - warn_infobar_delegate_(NULL) {}
|
| + warn_infobar_delegate_(NULL),
|
| + preview_infobar_delegate_(NULL),
|
| + state_(RECORDING_URLS_BEFORE_PREVIEW),
|
| + last_allowed_page_(-1) {}
|
| +
|
| +void ManagedModeNavigationObserver::AddTemporaryException() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(web_contents());
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(&ManagedModeResourceThrottle::AddTemporaryException,
|
| + web_contents()->GetRenderProcessHost()->GetID(),
|
| + web_contents()->GetRenderViewHost()->GetRoutingID(),
|
| + last_url_));
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::RemoveTemporaryException() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + // When closing the browser web_contents() may return NULL so guard against
|
| + // that.
|
| + if (!web_contents())
|
| + return;
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(&ManagedModeResourceThrottle::RemoveTemporaryException,
|
| + web_contents()->GetRenderProcessHost()->GetID(),
|
| + web_contents()->GetRenderViewHost()->GetRoutingID()));
|
| +}
|
|
|
| void ManagedModeNavigationObserver::WarnInfobarDismissed() {
|
| DCHECK(warn_infobar_delegate_);
|
| warn_infobar_delegate_ = NULL;
|
| }
|
|
|
| +void ManagedModeNavigationObserver::PreviewInfobarDismissed() {
|
| + DCHECK(preview_infobar_delegate_);
|
| + preview_infobar_delegate_ = NULL;
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::AddSavedURLsToWhitelistAndClearState() {
|
| + ListValue whitelist;
|
| + for (std::set<GURL>::const_iterator it = navigated_urls_.begin();
|
| + it != navigated_urls_.end();
|
| + ++it) {
|
| + whitelist.AppendString(it->scheme() + "://." + it->host() + it->path());
|
| + }
|
| + if (last_url_.is_valid()) {
|
| + if (last_url_.SchemeIs("https")) {
|
| + whitelist.AppendString("https://" + last_url_.host());
|
| + } else {
|
| + whitelist.AppendString(last_url_.host());
|
| + }
|
| + }
|
| + ManagedMode::AddToManualList(true, whitelist);
|
| + ClearObserverState();
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::AddURLToPatternList(const GURL& url) {
|
| + DCHECK(state_ != NOT_RECORDING_URLS);
|
| + navigated_urls_.insert(url);
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::AddURLAsLastPattern(const GURL& url) {
|
| + DCHECK(state_ != NOT_RECORDING_URLS);
|
| +
|
| + // Erase the last |url| if it is present in the |navigated_urls_|. This stops
|
| + // us from having both http://.www.google.com (exact URL from the pattern
|
| + // list) and www.google.com (hostname from the last URL pattern) in the list.
|
| + navigated_urls_.erase(url);
|
| + last_url_ = url;
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::SetStateToRecordingAfterPreview() {
|
| + state_ = RECORDING_URLS_AFTER_PREVIEW;
|
| +}
|
| +
|
| +bool ManagedModeNavigationObserver::CanTemporarilyNavigateHost(
|
| + const GURL& url) {
|
| + if (last_url_.scheme() == "https") {
|
| + return url.scheme() == "https" && last_url_.host() == url.host();
|
| + }
|
| + return last_url_.host() == url.host();
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::ClearObserverState() {
|
| + if (state_ == NOT_RECORDING_URLS && preview_infobar_delegate_) {
|
| + InfoBarService* infobar_service =
|
| + InfoBarService::FromWebContents(web_contents());
|
| + infobar_service->RemoveInfoBar(preview_infobar_delegate_);
|
| + preview_infobar_delegate_ = NULL;
|
| + }
|
| + navigated_urls_.clear();
|
| + last_url_ = GURL();
|
| + state_ = RECORDING_URLS_BEFORE_PREVIEW;
|
| + RemoveTemporaryException();
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::NavigateToPendingEntry(
|
| + const GURL& url,
|
| + content::NavigationController::ReloadType reload_type) {
|
| +
|
| + // This method gets called first when a user navigates to a (new) URL.
|
| + // This means that the data related to the list of URLs needs to be cleared
|
| + // in certain circumstances.
|
| + if (web_contents()->GetController().GetCurrentEntryIndex() <
|
| + last_allowed_page_ || !CanTemporarilyNavigateHost(url)) {
|
| + ClearObserverState();
|
| + }
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::DidNavigateMainFrame(
|
| + const content::LoadCommittedDetails& details,
|
| + const content::FrameNavigateParams& params) {
|
| +
|
| + ManagedModeURLFilter::FilteringBehavior behavior =
|
| + url_filter_->GetFilteringBehaviorForURL(params.url);
|
| +
|
| + // If the user just saw an interstitial this is the final URL so it is
|
| + // recorded. Checking for filtering behavior here isn't useful because
|
| + // although this specific URL can be allowed the hostname will be added which
|
| + // is more general. The hostname will be checked later when it is
|
| + // added to the actual whitelist to see if it is already present.
|
| + if (behavior == ManagedModeURLFilter::BLOCK && state_ != NOT_RECORDING_URLS)
|
| + AddURLAsLastPattern(params.url);
|
| +
|
| + if (behavior == ManagedModeURLFilter::ALLOW &&
|
| + state_ != RECORDING_URLS_BEFORE_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.
|
| + AddSavedURLsToWhitelistAndClearState();
|
| + InfoBarService* infobar_service =
|
| + InfoBarService::FromWebContents(web_contents());
|
| + infobar_service->AddInfoBar(new SimpleAlertInfoBarDelegate(
|
| + infobar_service,
|
| + NULL,
|
| + l10n_util::GetStringUTF16(IDS_MANAGED_MODE_ALREADY_ADDED_MESSAGE),
|
| + true));
|
| + return;
|
| + }
|
| +
|
| + if (state_ == RECORDING_URLS_AFTER_PREVIEW) {
|
| + // A temporary exception should be added only if an interstitial was shown,
|
| + // the user clicked preview and the final page was not allowed. This
|
| + // temporary exception stops the interstitial from showing on further
|
| + // navigations to that host so that the user can navigate around to
|
| + // inspect it.
|
| + state_ = NOT_RECORDING_URLS;
|
| + AddTemporaryException();
|
| + }
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::DidStartProvisionalLoadForFrame(
|
| + int64 frame_id,
|
| + int64 parent_frame_id,
|
| + bool is_main_frame,
|
| + const GURL& url,
|
| + bool is_error_page,
|
| + content::RenderViewHost* render_view_host) {
|
| + if (!is_main_frame)
|
| + return;
|
| +}
|
| +
|
| +void ManagedModeNavigationObserver::ProvisionalChangeToMainFrameUrl(
|
| + const GURL& url,
|
| + content::RenderViewHost* render_view_host) {
|
| + // This function is the last one to be called before the resource throttle
|
| + // shows the interstitial if the URL must be blocked.
|
| + ManagedModeURLFilter::FilteringBehavior behavior =
|
| + url_filter_->GetFilteringBehaviorForURL(url);
|
| +
|
| + if (state_ == NOT_RECORDING_URLS && !CanTemporarilyNavigateHost(url))
|
| + ClearObserverState();
|
| +
|
| + if (behavior == ManagedModeURLFilter::BLOCK && state_ != NOT_RECORDING_URLS)
|
| + AddURLToPatternList(url);
|
| +}
|
| +
|
| void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
|
| int64 frame_id,
|
| bool is_main_frame,
|
| @@ -141,7 +410,8 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
|
| InfoBarService* infobar_service =
|
| InfoBarService::FromWebContents(web_contents());
|
| warn_infobar_delegate_ =
|
| - new ManagedModeWarningInfobarDelegate(infobar_service);
|
| + new ManagedModeWarningInfobarDelegate(infobar_service,
|
| + last_allowed_page_);
|
| infobar_service->AddInfoBar(warn_infobar_delegate_);
|
| }
|
| } else {
|
| @@ -149,8 +419,33 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
|
| InfoBarService* infobar_service =
|
| InfoBarService::FromWebContents(web_contents());
|
| infobar_service->RemoveInfoBar(warn_infobar_delegate_);
|
| - warn_infobar_delegate_= NULL;
|
| + warn_infobar_delegate_ = NULL;
|
| + }
|
| + }
|
| +
|
| + if (behavior == ManagedModeURLFilter::BLOCK) {
|
| + switch (state_) {
|
| + case RECORDING_URLS_BEFORE_PREVIEW:
|
| + // Should not be in this state with a blocked URL.
|
| + NOTREACHED();
|
| + break;
|
| + case RECORDING_URLS_AFTER_PREVIEW:
|
| + // Add the infobar.
|
| + if (!preview_infobar_delegate_) {
|
| + InfoBarService* infobar_service =
|
| + InfoBarService::FromWebContents(web_contents());
|
| + preview_infobar_delegate_ =
|
| + new ManagedModePreviewInfobarDelegate(infobar_service);
|
| + infobar_service->AddInfoBar(preview_infobar_delegate_);
|
| + }
|
| + break;
|
| + case NOT_RECORDING_URLS:
|
| + // Check that the infobar is present.
|
| + DCHECK(preview_infobar_delegate_);
|
| + break;
|
| }
|
| }
|
|
|
| + if (behavior == ManagedModeURLFilter::ALLOW)
|
| + last_allowed_page_ = web_contents()->GetController().GetCurrentEntryIndex();
|
| }
|
|
|