Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / managed_mode / managed_mode_navigation_observer.cc
blobbd06cafedd2b045038b760ddc2abf159ce568eb8
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_util.h"
11 #include "chrome/browser/history/history_service.h"
12 #include "chrome/browser/history/history_service_factory.h"
13 #include "chrome/browser/history/history_types.h"
14 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
15 #include "chrome/browser/infobars/infobar.h"
16 #include "chrome/browser/infobars/infobar_service.h"
17 #include "chrome/browser/managed_mode/managed_mode_interstitial.h"
18 #include "chrome/browser/managed_mode/managed_mode_resource_throttle.h"
19 #include "chrome/browser/managed_mode/managed_mode_url_filter.h"
20 #include "chrome/browser/managed_mode/managed_user_service.h"
21 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/tab_contents/tab_util.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/render_process_host.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/user_metrics.h"
29 #include "content/public/browser/web_contents_view.h"
30 #include "grit/generated_resources.h"
31 #include "ui/base/l10n/l10n_util.h"
33 #if !defined(OS_ANDROID)
34 #include "chrome/browser/ui/browser.h"
35 #include "chrome/browser/ui/browser_commands.h"
36 #include "chrome/browser/ui/browser_finder.h"
37 #include "chrome/browser/ui/browser_list.h"
38 #include "chrome/browser/ui/host_desktop.h"
39 #include "chrome/browser/ui/tabs/tab_strip_model.h"
40 #endif
42 using base::Time;
43 using content::NavigationEntry;
45 namespace {
48 // Helpers --------------------------------------------------------------------
50 #if !defined(OS_ANDROID)
51 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
52 // http://crbug.com/313377
53 void GoBackToSafety(content::WebContents* web_contents) {
54 // For now, just go back one page (the user didn't retreat from that page,
55 // so it should be okay).
56 content::NavigationController* controller =
57 &web_contents->GetController();
58 if (controller->CanGoBack()) {
59 controller->GoBack();
60 return;
63 // If we can't go back (because we opened a new tab), try to close the tab.
64 // If this is the last tab on this desktop, open a new window.
65 chrome::HostDesktopType host_desktop_type =
66 chrome::GetHostDesktopTypeForNativeView(
67 web_contents->GetView()->GetNativeView());
68 const BrowserList* browser_list = BrowserList::GetInstance(host_desktop_type);
69 if (browser_list->size() == 1) {
70 Browser* browser = browser_list->get(0);
71 DCHECK(browser == chrome::FindBrowserWithWebContents(web_contents));
72 if (browser->tab_strip_model()->count() == 1)
73 chrome::NewEmptyWindow(browser->profile(), browser->host_desktop_type());
76 web_contents->GetDelegate()->CloseContents(web_contents);
78 #endif
80 // ManagedModeWarningInfoBarDelegate ------------------------------------------
82 class ManagedModeWarningInfoBarDelegate : public ConfirmInfoBarDelegate {
83 public:
84 // Creates a managed mode warning infobar and delegate and adds the infobar to
85 // |infobar_service|. Returns the infobar if it was successfully added.
86 static InfoBar* Create(InfoBarService* infobar_service);
88 private:
89 ManagedModeWarningInfoBarDelegate();
90 virtual ~ManagedModeWarningInfoBarDelegate();
92 // ConfirmInfoBarDelegate:
93 virtual bool ShouldExpire(
94 const content::LoadCommittedDetails& details) const OVERRIDE;
95 virtual void InfoBarDismissed() OVERRIDE;
96 virtual base::string16 GetMessageText() const OVERRIDE;
97 virtual int GetButtons() const OVERRIDE;
98 virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
99 virtual bool Accept() OVERRIDE;
101 DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfoBarDelegate);
104 // static
105 InfoBar* ManagedModeWarningInfoBarDelegate::Create(
106 InfoBarService* infobar_service) {
107 return infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
108 scoped_ptr<ConfirmInfoBarDelegate>(
109 new ManagedModeWarningInfoBarDelegate())));
112 ManagedModeWarningInfoBarDelegate::ManagedModeWarningInfoBarDelegate()
113 : ConfirmInfoBarDelegate() {
116 ManagedModeWarningInfoBarDelegate::~ManagedModeWarningInfoBarDelegate() {
119 bool ManagedModeWarningInfoBarDelegate::ShouldExpire(
120 const content::LoadCommittedDetails& details) const {
121 // ManagedModeNavigationObserver removes us below.
122 return false;
125 void ManagedModeWarningInfoBarDelegate::InfoBarDismissed() {
126 ManagedModeNavigationObserver::FromWebContents(
127 web_contents())->WarnInfoBarDismissed();
130 base::string16 ManagedModeWarningInfoBarDelegate::GetMessageText() const {
131 return l10n_util::GetStringUTF16(IDS_MANAGED_USER_WARN_INFOBAR_MESSAGE);
134 int ManagedModeWarningInfoBarDelegate::GetButtons() const {
135 return BUTTON_OK;
138 base::string16 ManagedModeWarningInfoBarDelegate::GetButtonLabel(
139 InfoBarButton button) const {
140 DCHECK_EQ(BUTTON_OK, button);
141 return l10n_util::GetStringUTF16(IDS_MANAGED_USER_WARN_INFOBAR_GO_BACK);
144 bool ManagedModeWarningInfoBarDelegate::Accept() {
145 #if defined(OS_ANDROID)
146 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
147 // http://crbug.com/313377
148 NOTIMPLEMENTED();
149 #else
150 GoBackToSafety(web_contents());
151 #endif
153 return false;
157 } // namespace
159 // ManagedModeNavigationObserver ----------------------------------------------
161 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagedModeNavigationObserver);
163 ManagedModeNavigationObserver::~ManagedModeNavigationObserver() {
166 ManagedModeNavigationObserver::ManagedModeNavigationObserver(
167 content::WebContents* web_contents)
168 : WebContentsObserver(web_contents),
169 warn_infobar_(NULL) {
170 Profile* profile =
171 Profile::FromBrowserContext(web_contents->GetBrowserContext());
172 managed_user_service_ = ManagedUserServiceFactory::GetForProfile(profile);
173 url_filter_ = managed_user_service_->GetURLFilterForUIThread();
176 void ManagedModeNavigationObserver::WarnInfoBarDismissed() {
177 DCHECK(warn_infobar_);
178 warn_infobar_ = NULL;
181 void ManagedModeNavigationObserver::ProvisionalChangeToMainFrameUrl(
182 const GURL& url,
183 content::RenderFrameHost* render_frame_host) {
184 ManagedModeURLFilter::FilteringBehavior behavior =
185 url_filter_->GetFilteringBehaviorForURL(url);
187 if (behavior == ManagedModeURLFilter::WARN || !warn_infobar_)
188 return;
190 // If we shouldn't have a warn infobar remove it here.
191 InfoBarService::FromWebContents(web_contents())->RemoveInfoBar(warn_infobar_);
192 warn_infobar_ = NULL;
195 void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
196 int64 frame_id,
197 const base::string16& frame_unique_name,
198 bool is_main_frame,
199 const GURL& url,
200 content::PageTransition transition_type,
201 content::RenderViewHost* render_view_host) {
202 if (!is_main_frame)
203 return;
205 DVLOG(1) << "DidCommitProvisionalLoadForFrame " << url.spec();
206 ManagedModeURLFilter::FilteringBehavior behavior =
207 url_filter_->GetFilteringBehaviorForURL(url);
209 if (behavior == ManagedModeURLFilter::WARN && !warn_infobar_) {
210 warn_infobar_ = ManagedModeWarningInfoBarDelegate::Create(
211 InfoBarService::FromWebContents(web_contents()));
215 // static
216 void ManagedModeNavigationObserver::OnRequestBlocked(
217 int render_process_host_id,
218 int render_view_id,
219 const GURL& url,
220 const base::Callback<void(bool)>& callback) {
221 content::WebContents* web_contents =
222 tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
223 if (!web_contents) {
224 content::BrowserThread::PostTask(
225 content::BrowserThread::IO, FROM_HERE, base::Bind(callback, false));
226 return;
229 ManagedModeNavigationObserver* navigation_observer =
230 ManagedModeNavigationObserver::FromWebContents(web_contents);
231 if (navigation_observer)
232 navigation_observer->OnRequestBlockedInternal(url);
234 // Show the interstitial.
235 new ManagedModeInterstitial(web_contents, url, callback);
238 void ManagedModeNavigationObserver::OnRequestBlockedInternal(const GURL& url) {
239 Time timestamp = Time::Now(); // TODO(bauerb): Use SaneTime when available.
240 // Create a history entry for the attempt and mark it as such.
241 history::HistoryAddPageArgs add_page_args(
242 url, timestamp, web_contents(), 0,
243 url, history::RedirectList(),
244 content::PAGE_TRANSITION_BLOCKED, history::SOURCE_BROWSED,
245 false);
247 // Add the entry to the history database.
248 Profile* profile =
249 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
250 HistoryService* history_service =
251 HistoryServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
253 // |history_service| is null if saving history is disabled.
254 if (history_service)
255 history_service->AddPage(add_page_args);
257 scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
258 entry->SetVirtualURL(url);
259 entry->SetTimestamp(timestamp);
260 blocked_navigations_.push_back(entry.release());
261 ManagedUserService* managed_user_service =
262 ManagedUserServiceFactory::GetForProfile(profile);
263 managed_user_service->DidBlockNavigation(web_contents());