Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: components/data_reduction_proxy/content/browser/data_reduction_proxy_blocking_page.cc

Issue 830503004: Data Reduction Proxy blocking page and resources (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@interstitalStep1
Patch Set: Rebase and crash fixes Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "components/data_reduction_proxy/content/browser/data_reduction_proxy_b locking_page.h"
6
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/string_piece.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "content/public/browser/interstitial_page.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "grit/components_resources.h"
17 #include "grit/components_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/base/webui/jstemplate_builder.h"
21 #include "ui/base/webui/web_ui_util.h"
22
23 namespace data_reduction_proxy {
24
25 namespace {
26
27 // The commands returned by the page when the user performs an action.
28 const char kProceedCommand[] = "proceed";
29 const char kTakeMeBackCommand[] = "takeMeBack";
30
31 base::LazyInstance<DataReductionProxyBlockingPage::BypassResourceMap>
32 g_bypass_resource_map = LAZY_INSTANCE_INITIALIZER;
33
34 } // namespace
35
36 // static
37 DataReductionProxyBlockingPageFactory*
38 DataReductionProxyBlockingPage::factory_ = NULL;
39
40 // The default DataReductionProxyBlockingPageFactory. Global, made a singleton
41 // so it isn't leaked.
42 class DataReductionProxyBlockingPageFactoryImpl
43 : public DataReductionProxyBlockingPageFactory {
44 public:
45 virtual DataReductionProxyBlockingPage* CreateDataReductionProxyPage(
46 DataReductionProxyUIManager* ui_manager,
47 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
48 content::WebContents* web_contents,
49 const DataReductionProxyBlockingPage::BypassResourceList& resource_list)
50 override {
51 return new DataReductionProxyBlockingPage(ui_manager, io_task_runner,
52 web_contents, resource_list);
53 }
54
55 private:
56 friend struct base::DefaultLazyInstanceTraits<
57 DataReductionProxyBlockingPageFactoryImpl>;
58
59 DataReductionProxyBlockingPageFactoryImpl() {
60 }
61
62 DISALLOW_COPY_AND_ASSIGN(DataReductionProxyBlockingPageFactoryImpl);
63 };
64
65 static base::LazyInstance<DataReductionProxyBlockingPageFactoryImpl>
66 g_data_reduction_proxy_blocking_page_factory_impl =
67 LAZY_INSTANCE_INITIALIZER;
68
69 DataReductionProxyBlockingPage::DataReductionProxyBlockingPage(
70 DataReductionProxyUIManager* ui_manager,
71 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
72 content::WebContents* web_contents,
73 const BypassResourceList& resource_list)
74 : ui_manager_(ui_manager),
75 io_task_runner_(io_task_runner),
76 is_main_frame_load_blocked_(IsMainPageLoadBlocked(resource_list)),
77 resource_list_(resource_list),
78 proceeded_(false),
79 web_contents_(web_contents),
80 url_(resource_list[0].url),
81 interstitial_page_(NULL),
82 create_view_(true) {
83 if (!is_main_frame_load_blocked_) {
84 navigation_entry_index_to_remove_ =
85 web_contents->GetController().GetLastCommittedEntryIndex();
86 } else {
87 navigation_entry_index_to_remove_ = -1;
88 }
89 // Creating interstitial_page_ without showing it leaks memory, so don't
90 // create it here.
91 }
92
93 DataReductionProxyBlockingPage::~DataReductionProxyBlockingPage() {
94 }
95
96 content::InterstitialPage*
97 DataReductionProxyBlockingPage::interstitial_page() const {
98 return interstitial_page_;
99 }
100
101 void DataReductionProxyBlockingPage::CommandReceived(const std::string& cmd) {
102 // Make a local copy so it can be modified.
103 std::string command(cmd);
104 // The Jasonified response has quotes, remove them.
105 if (command.length() > 1 && command[0] == '"') {
106 command = command.substr(1, command.length() - 2);
107 }
108
109 if (command == kProceedCommand) {
110 interstitial_page_->Proceed();
111 // |this| has been deleted after Proceed() returns.
112 return;
113 }
114
115 if (command == kTakeMeBackCommand) {
116 if (is_main_frame_load_blocked_) {
117 // If the load is blocked, close the interstitial and discard the pending
118 // entry.
119 interstitial_page_->DontProceed();
120 // |this| has been deleted after DontProceed() returns.
121 return;
122 }
123
124 // Otherwise the offending entry has committed, so go back or to a new page.
125 // Close the interstitial when that page commits.
126 if (web_contents_->GetController().CanGoBack()) {
127 web_contents_->GetController().GoBack();
128 } else {
129 web_contents_->GetController().LoadURL(
130 GURL("chrome://newtab/"),
131 content::Referrer(),
132 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
133 std::string());
134 }
135 return;
136 }
137 }
138
139 void DataReductionProxyBlockingPage::OnProceed() {
140 proceeded_ = true;
141
142 NotifyDataReductionProxyUIManager(ui_manager_, io_task_runner_,
143 resource_list_, true);
144
145 // The user is proceeding, an interstitial will not be shown again for a
146 // predetermined amount of time. Clear the queued resource notifications
147 // received while the interstitial was showing.
148 BypassResourceMap* resource_map = GetBypassResourcesMap();
149 BypassResourceMap::iterator iter = resource_map->find(web_contents_);
150 if (iter != resource_map->end() && !iter->second.empty()) {
151 NotifyDataReductionProxyUIManager(ui_manager_, io_task_runner_,
152 iter->second, true);
153 resource_map->erase(iter);
154 }
155 }
156
157 void DataReductionProxyBlockingPage::Show() {
158 DCHECK(!interstitial_page_);
159 interstitial_page_ = content::InterstitialPage::Create(
160 web_contents_, is_main_frame_load_blocked_, url_, this);
161 if (!create_view_)
162 interstitial_page_->DontCreateViewForTesting();
163 interstitial_page_->Show();
164 }
165
166 void DataReductionProxyBlockingPage::OnDontProceed() {
167 // Proceed() could have already been called, in which case do not notify the
168 // DataReductionProxyUIManager again, as the client has been deleted.
169 if (proceeded_)
170 return;
171
172 NotifyDataReductionProxyUIManager(ui_manager_, io_task_runner_,
173 resource_list_, false);
174
175 // The user does not want to proceed, clear the queued resource notifications
176 // received while the interstitial was showing.
177 BypassResourceMap* resource_map = GetBypassResourcesMap();
178 BypassResourceMap::iterator iter = resource_map->find(web_contents_);
179 if (iter != resource_map->end() && !iter->second.empty()) {
180 NotifyDataReductionProxyUIManager(ui_manager_, io_task_runner_,
181 iter->second, false);
182 resource_map->erase(iter);
183 }
184
185 // Don't remove the navigation entry if the tab is being destroyed as this
186 // would trigger a navigation that would cause trouble as the render view host
187 // for the tab has by then already been destroyed. Also, don't delete the
188 // current entry if it has been committed again, which is possible on a page
189 // that had a subresource warning.
190 int last_committed_index =
191 web_contents_->GetController().GetLastCommittedEntryIndex();
192 if (navigation_entry_index_to_remove_ != -1 &&
193 navigation_entry_index_to_remove_ != last_committed_index &&
194 !web_contents_->IsBeingDestroyed()) {
195 CHECK(web_contents_->GetController().RemoveEntryAtIndex(
196 navigation_entry_index_to_remove_));
197 navigation_entry_index_to_remove_ = -1;
198 }
199 }
200
201 // static
202 void DataReductionProxyBlockingPage::NotifyDataReductionProxyUIManager(
203 DataReductionProxyUIManager* ui_manager,
204 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
205 const BypassResourceList& resource_list,
206 bool proceed) {
207 io_task_runner->PostTask(
208 FROM_HERE,
209 base::Bind(&DataReductionProxyUIManager::OnBlockingPageDone,
210 ui_manager, resource_list, proceed));
211 }
212
213 // static
214 DataReductionProxyBlockingPage::BypassResourceMap*
215 DataReductionProxyBlockingPage::GetBypassResourcesMap() {
216 return g_bypass_resource_map.Pointer();
217 }
218
219 void DataReductionProxyBlockingPage::DontCreateViewForTesting() {
220 create_view_ = false;
221 }
222
223 // static
224 DataReductionProxyBlockingPage*
225 DataReductionProxyBlockingPage::CreateBlockingPage(
226 DataReductionProxyUIManager* ui_manager,
227 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
228 content::WebContents* web_contents,
229 const BypassResource& bypass_resource) {
230 std::vector<BypassResource> resources;
231 resources.push_back(bypass_resource);
232 // Set up the factory if this has not been done already (tests do that
233 // before this method is called).
234 if (!factory_)
235 factory_ = g_data_reduction_proxy_blocking_page_factory_impl.Pointer();
236 return factory_->CreateDataReductionProxyPage(ui_manager, io_task_runner,
237 web_contents, resources);
238 }
239
240 // static
241 void DataReductionProxyBlockingPage::ShowBlockingPage(
242 DataReductionProxyUIManager* ui_manager,
243 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
244 const BypassResource& bypass_resource) {
245 content::RenderViewHost* render_view_host =
246 content:: RenderViewHost::FromID(bypass_resource.render_process_host_id,
247 bypass_resource.render_view_id);
248 content::WebContents* web_contents = nullptr;
249 if (render_view_host)
250 web_contents = content::WebContents::FromRenderViewHost(render_view_host);
251
252 content::InterstitialPage* interstitial =
253 content::InterstitialPage::GetInterstitialPage(web_contents);
254 if (interstitial && !bypass_resource.is_subresource) {
255 // There is already an interstitial showing and a new one for the main frame
256 // is about to be displayed. Just hide the current one, it is now
257 // irrelevent.
258 interstitial->DontProceed();
259 interstitial = NULL;
260 }
261
262 if (!interstitial) {
263 // There is no interstitial currently showing in that tab, go ahead and
264 // show this interstitial.
265 DataReductionProxyBlockingPage* blocking_page =
266 CreateBlockingPage(ui_manager, io_task_runner, web_contents,
267 bypass_resource);
268 blocking_page->Show();
269 return;
270 }
271
272 // This is an interstitial for a page's resource, let's queue it.
273 BypassResourceMap* bypassed_resource_map = GetBypassResourcesMap();
274 (*bypassed_resource_map)[web_contents].push_back(bypass_resource);
275 }
276
277 // static
278 bool DataReductionProxyBlockingPage::IsMainPageLoadBlocked(
279 const BypassResourceList& resource_list) {
280 return resource_list.size() == 1 && !resource_list[0].is_subresource;
281 }
282
283 std::string DataReductionProxyBlockingPage::GetHTMLContents() {
284 DCHECK(!resource_list_.empty());
285
286 base::DictionaryValue load_time_data;
287 webui::SetFontAndTextDirection(&load_time_data);
288 load_time_data.SetString(
289 "tabTitle", l10n_util::GetStringUTF16(IDS_DATA_REDUCTION_PROXY_TITLE));
290 load_time_data.SetString(
291 "primaryButtonText",
292 l10n_util::GetStringUTF16(IDS_DATA_REDUCTION_PROXY_BACK_BUTTON));
293 load_time_data.SetString(
294 "secondaryButtonText",
295 l10n_util::GetStringUTF16(IDS_DATA_REDUCTION_PROXY_CONTINUE_BUTTON));
296 load_time_data.SetString(
297 "heading", l10n_util::GetStringUTF16(IDS_UNPROXYABLE_HEADING));
298 load_time_data.SetString(
299 "primaryParagraph",
300 l10n_util::GetStringFUTF16(IDS_UNPROXYABLE_PRIMARY_PARAGRAPH,
301 base::UTF8ToUTF16(url_.host())));
302 load_time_data.SetString(
303 "secondaryParagraph",
304 l10n_util::GetStringUTF16(IDS_UNPROXYABLE_SECONDARY_PARAGRAPH));
305
306 base::StringPiece html(
307 ResourceBundle::GetSharedInstance().GetRawDataResource(
308 IDR_DATA_REDUCTION_PROXY_INTERSTITIAL_HTML));
309 return webui::GetI18nTemplateHtml(html, &load_time_data);
310 }
311
312 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698