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

Side by Side Diff: chrome/browser/ssl/ssl_error_handler.cc

Issue 318213002: Add custom interstitial for captive portals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix android tests, add more uma, address mmenke's comments Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014 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/ssl/ssl_error_handler.h"
6
7 #include "base/metrics/histogram.h"
8 #include "base/time/time.h"
9 #include "base/timer/timer.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ssl/captive_portal_blocking_page.h"
12 #include "chrome/browser/ssl/ssl_blocking_page.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/web_contents.h"
16
17 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
18 #include "chrome/browser/captive_portal/captive_portal_service.h"
19 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
20 #endif
21
22 namespace {
23 // The delay before displaying the SSL interstitial, during which we wait for a
24 // captive portal result.
25 const int kDefaultSSLInterstitialDisplayDelay = 2;
26
27 // Events for UMA.
28 enum SSLErrorHandlerEvent {
29 HANDLE_ALL,
30 CAPTIVE_PORTAL_CHECK,
31 CAPTIVE_PORTAL_RESULT_ALREADY_HANDLED,
32 CAPTIVE_PORTAL_RESULT_BEFORE_TIMER,
33 SSL_WARNING_ALREADY_HANDLED,
34 SHOW_CAPTIVE_PORTAL_INTERSTITIAL,
35 SHOW_SSL_INTERSTITIAL,
36 SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK,
37 SSL_ERROR_HANDLER_EVENT_COUNT
38 };
39
40 void RecordUMA(SSLErrorHandlerEvent event) {
41 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler",
42 event,
43 SSL_ERROR_HANDLER_EVENT_COUNT);
44 }
45
46 } // namespace
47
48 SSLErrorHandler::SSLErrorHandler(content::WebContents* web_contents,
49 int cert_error,
50 const net::SSLInfo& ssl_info,
51 const GURL& request_url,
52 bool overridable,
53 bool strict_enforcement,
54 const base::Callback<void(bool)>& callback)
55 : content::WebContentsObserver(web_contents),
56 web_contents_(web_contents),
57 cert_error_(cert_error),
58 ssl_info_(ssl_info),
59 request_url_(request_url),
60 overridable_(overridable),
61 strict_enforcement_(strict_enforcement),
62 callback_(callback),
63 handled_(false),
64 ssl_interstitial_display_delay_(
65 base::TimeDelta::FromSeconds(kDefaultSSLInterstitialDisplayDelay)) {
66 }
67
68 SSLErrorHandler::~SSLErrorHandler() {
69 }
70
71 void SSLErrorHandler::Handle() {
72 RecordUMA(HANDLE_ALL);
73 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
74 CheckForCaptivePortal();
75 timer_.Start(FROM_HERE, ssl_interstitial_display_delay_,
76 base::Bind(&SSLErrorHandler::OnTimerExpired,
77 base::Unretained(this)));
78 #else
79 RecordUMA(SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK);
80 ShowSSLInterstitial();
81 handled_ = true;
82 #endif
83 }
84
85 void SSLErrorHandler::CheckForCaptivePortal() {
86 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
87 RecordUMA(CAPTIVE_PORTAL_CHECK);
88 Profile* profile = Profile::FromBrowserContext(
89 web_contents_->GetBrowserContext());
90 CaptivePortalService* captive_portal_service =
91 CaptivePortalServiceFactory::GetForProfile(profile);
92 captive_portal_service->DetectCaptivePortal();
93 registrar_.Add(this,
94 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
95 content::Source<Profile>(profile));
96 #endif
97 }
98
99 void SSLErrorHandler::Observe(
100 int type,
101 const content::NotificationSource& source,
102 const content::NotificationDetails& details) {
103 // TODO(meacer): Refactor this method in SSLBlockingPage.
104 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
105 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
106 CaptivePortalService::Results* results =
107 content::Details<CaptivePortalService::Results>(details).ptr();
108 if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL)
109 OnCaptivePortalResult();
110 }
111 #endif
112 }
113
114 void SSLErrorHandler::OnCaptivePortalResult() {
115 if (!timer_.IsRunning()) {
116 RecordUMA(CAPTIVE_PORTAL_RESULT_BEFORE_TIMER);
117 return;
118 }
119 if (handled_) {
120 RecordUMA(CAPTIVE_PORTAL_RESULT_ALREADY_HANDLED);
121 return;
122 }
123 timer_.Stop();
124 ShowCaptivePortalInterstitial();
125 handled_ = true;
mmenke 2014/06/20 16:07:09 We just keep the handler around until some random
meacer 2014/06/20 23:28:15 Once we show the captive portal interstitial, the
126 }
127
128 void SSLErrorHandler::OnTimerExpired() {
129 if (handled_) {
130 RecordUMA(SSL_WARNING_ALREADY_HANDLED);
131 return;
132 }
133 ShowSSLInterstitial();
134 handled_ = true;
135 }
136
137 void SSLErrorHandler::ShowCaptivePortalInterstitial() {
138 // Show captive portal blocking page. The interstitial owns the blocking page.
139 RecordUMA(SHOW_CAPTIVE_PORTAL_INTERSTITIAL);
140 new CaptivePortalBlockingPage(web_contents_, request_url_);
141 }
142
143 void SSLErrorHandler::ShowSSLInterstitial() {
144 // Show SSL blocking page. The interstitial owns the blocking page.
145 RecordUMA(SHOW_SSL_INTERSTITIAL);
146 new SSLBlockingPage(web_contents_, cert_error_, ssl_info_, request_url_,
147 overridable_, strict_enforcement_, callback_);
148 }
149
150 void SSLErrorHandler::DidStopLoading(
mmenke 2014/06/20 16:07:09 Should also destroy the handler on a new load. No
mmenke 2014/06/20 16:07:09 What if the user presses the stop button?
meacer 2014/06/20 23:28:15 In which case do we get a new load notification on
meacer 2014/06/20 23:28:15 In that case we'll get a DidStopLoading and delete
151 content::RenderViewHost* render_view_host) {
152 timer_.Stop();
mmenke 2014/06/20 16:07:09 Not need to stop the timer. Destroying ourselves
meacer 2014/06/20 23:28:15 Done.
153 delete this;
154 }
155
156 void SSLErrorHandler::WebContentsDestroyed() {
157 timer_.Stop();
158 delete this;
159 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698