Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / managed_mode / managed_mode_interstitial.cc
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.
4
5 #include "chrome/browser/managed_mode/managed_mode_interstitial.h"
6
7 #include "base/i18n/rtl.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/managed_mode/managed_user_service.h"
14 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/infobars/core/infobar.h"
18 #include "components/infobars/core/infobar_delegate.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/interstitial_page.h"
21 #include "content/public/browser/navigation_controller.h"
22 #include "content/public/browser/navigation_details.h"
23 #include "content/public/browser/navigation_entry.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_ui.h"
26 #include "grit/browser_resources.h"
27 #include "grit/generated_resources.h"
28 #include "net/base/net_util.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/base/webui/jstemplate_builder.h"
32 #include "ui/base/webui/web_ui_util.h"
33
34 using content::BrowserThread;
35
36 // static
37 void ManagedModeInterstitial::Show(content::WebContents* web_contents,
38                                    const GURL& url,
39                                    const base::Callback<void(bool)>& callback) {
40   ManagedModeInterstitial* interstitial =
41       new ManagedModeInterstitial(web_contents, url, callback);
42
43   // If Init() does not complete fully, immediately delete the interstitial.
44   if (!interstitial->Init())
45     delete interstitial;
46   // Otherwise |interstitial_page_| is responsible for deleting it.
47 }
48
49 ManagedModeInterstitial::ManagedModeInterstitial(
50     content::WebContents* web_contents,
51     const GURL& url,
52     const base::Callback<void(bool)>& callback)
53     : web_contents_(web_contents),
54       interstitial_page_(NULL),
55       url_(url),
56       callback_(callback) {}
57
58 ManagedModeInterstitial::~ManagedModeInterstitial() {}
59
60 bool ManagedModeInterstitial::Init() {
61   if (ShouldProceed()) {
62     // It can happen that the site was only allowed very recently and the URL
63     // filter on the IO thread had not been updated yet. Proceed with the
64     // request without showing the interstitial.
65     DispatchContinueRequest(true);
66     return false;
67   }
68
69   InfoBarService* service = InfoBarService::FromWebContents(web_contents_);
70   if (service) {
71     // Remove all the infobars which are attached to |web_contents_| and for
72     // which ShouldExpire() returns true.
73     content::LoadCommittedDetails details;
74     // |details.is_in_page| is default false, and |details.is_main_frame| is
75     // default true. This results in is_navigation_to_different_page() returning
76     // true.
77     DCHECK(details.is_navigation_to_different_page());
78     const content::NavigationController& controller =
79         web_contents_->GetController();
80     details.entry = controller.GetActiveEntry();
81     if (controller.GetLastCommittedEntry()) {
82       details.previous_entry_index = controller.GetLastCommittedEntryIndex();
83       details.previous_url = controller.GetLastCommittedEntry()->GetURL();
84     }
85     details.type = content::NAVIGATION_TYPE_NEW_PAGE;
86     for (int i = service->infobar_count() - 1; i >= 0; --i) {
87       infobars::InfoBar* infobar = service->infobar_at(i);
88       if (infobar->delegate()->ShouldExpire(
89               InfoBarService::NavigationDetailsFromLoadCommittedDetails(
90                   details)))
91         service->RemoveInfoBar(infobar);
92     }
93   }
94
95   // TODO(bauerb): Extract an observer callback on ManagedUserService for this.
96   Profile* profile =
97       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
98   PrefService* prefs = profile->GetPrefs();
99   pref_change_registrar_.Init(prefs);
100   pref_change_registrar_.Add(
101       prefs::kDefaultManagedModeFilteringBehavior,
102       base::Bind(&ManagedModeInterstitial::OnFilteringPrefsChanged,
103                  base::Unretained(this)));
104   pref_change_registrar_.Add(
105       prefs::kManagedModeManualHosts,
106       base::Bind(&ManagedModeInterstitial::OnFilteringPrefsChanged,
107                  base::Unretained(this)));
108   pref_change_registrar_.Add(
109       prefs::kManagedModeManualURLs,
110       base::Bind(&ManagedModeInterstitial::OnFilteringPrefsChanged,
111                  base::Unretained(this)));
112
113   languages_ = prefs->GetString(prefs::kAcceptLanguages);
114   interstitial_page_ =
115       content::InterstitialPage::Create(web_contents_, true, url_, this);
116   interstitial_page_->Show();
117
118   return true;
119 }
120
121 std::string ManagedModeInterstitial::GetHTMLContents() {
122   base::DictionaryValue strings;
123   strings.SetString("blockPageTitle",
124                     l10n_util::GetStringUTF16(IDS_BLOCK_INTERSTITIAL_TITLE));
125
126   Profile* profile =
127       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
128   ManagedUserService* managed_user_service =
129       ManagedUserServiceFactory::GetForProfile(profile);
130
131   bool allow_access_requests = managed_user_service->AccessRequestsEnabled();
132   strings.SetBoolean("allowAccessRequests", allow_access_requests);
133
134   base::string16 custodian =
135       base::UTF8ToUTF16(managed_user_service->GetCustodianName());
136   strings.SetString(
137       "blockPageMessage",
138       allow_access_requests
139           ? l10n_util::GetStringFUTF16(IDS_BLOCK_INTERSTITIAL_MESSAGE,
140                                        custodian)
141           : l10n_util::GetStringUTF16(
142                 IDS_BLOCK_INTERSTITIAL_MESSAGE_ACCESS_REQUESTS_DISABLED));
143
144   strings.SetString("backButton", l10n_util::GetStringUTF16(IDS_BACK_BUTTON));
145   strings.SetString(
146       "requestAccessButton",
147       l10n_util::GetStringUTF16(IDS_BLOCK_INTERSTITIAL_REQUEST_ACCESS_BUTTON));
148
149   strings.SetString(
150       "requestSentMessage",
151       l10n_util::GetStringFUTF16(IDS_BLOCK_INTERSTITIAL_REQUEST_SENT_MESSAGE,
152                                  custodian));
153
154   webui::SetFontAndTextDirection(&strings);
155
156   base::StringPiece html(ResourceBundle::GetSharedInstance().GetRawDataResource(
157       IDR_MANAGED_MODE_BLOCK_INTERSTITIAL_HTML));
158
159   webui::UseVersion2 version;
160   return webui::GetI18nTemplateHtml(html, &strings);
161 }
162
163 void ManagedModeInterstitial::CommandReceived(const std::string& command) {
164   // For use in histograms.
165   enum Commands {
166     PREVIEW,
167     BACK,
168     NTP,
169     ACCESS_REQUEST,
170     HISTOGRAM_BOUNDING_VALUE
171   };
172
173   if (command == "\"back\"") {
174     UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand",
175                               BACK,
176                               HISTOGRAM_BOUNDING_VALUE);
177     interstitial_page_->DontProceed();
178     return;
179   }
180
181   if (command == "\"request\"") {
182     UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand",
183                               ACCESS_REQUEST,
184                               HISTOGRAM_BOUNDING_VALUE);
185
186     Profile* profile =
187         Profile::FromBrowserContext(web_contents_->GetBrowserContext());
188     ManagedUserService* managed_user_service =
189         ManagedUserServiceFactory::GetForProfile(profile);
190     managed_user_service->AddAccessRequest(url_);
191     DVLOG(1) << "Sent access request for " << url_.spec();
192
193     return;
194   }
195
196   NOTREACHED();
197 }
198
199 void ManagedModeInterstitial::OnProceed() {
200   // CHECK instead of DCHECK as defense in depth in case we'd accidentally
201   // proceed on a blocked page.
202   CHECK(ShouldProceed());
203   DispatchContinueRequest(true);
204 }
205
206 void ManagedModeInterstitial::OnDontProceed() {
207   DispatchContinueRequest(false);
208 }
209
210 bool ManagedModeInterstitial::ShouldProceed() {
211   Profile* profile =
212       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
213   ManagedUserService* managed_user_service =
214       ManagedUserServiceFactory::GetForProfile(profile);
215   ManagedModeURLFilter* url_filter =
216       managed_user_service->GetURLFilterForUIThread();
217   return url_filter->GetFilteringBehaviorForURL(url_) !=
218          ManagedModeURLFilter::BLOCK;
219 }
220
221 void ManagedModeInterstitial::OnFilteringPrefsChanged() {
222   if (ShouldProceed())
223     interstitial_page_->Proceed();
224 }
225
226 void ManagedModeInterstitial::DispatchContinueRequest(bool continue_request) {
227   // If there is no history entry to go back to, close the tab instead.
228   int nav_entry_count = web_contents_->GetController().GetEntryCount();
229   if (!continue_request && nav_entry_count == 0)
230     web_contents_->Close();
231
232   BrowserThread::PostTask(
233       BrowserThread::IO, FROM_HERE, base::Bind(callback_, continue_request));
234 }