Index: chrome/browser/ssl/ssl_error_classification.cc |
diff --git a/chrome/browser/ssl/ssl_error_classification.cc b/chrome/browser/ssl/ssl_error_classification.cc |
index ae9283c190f73594e2622102a2336d99b318f4c2..195603dcd523fa28ed0b8efa1c3ce7120c2621e3 100644 |
--- a/chrome/browser/ssl/ssl_error_classification.cc |
+++ b/chrome/browser/ssl/ssl_error_classification.cc |
@@ -9,9 +9,18 @@ |
#include "base/metrics/histogram.h" |
#include "base/time/time.h" |
#include "chrome/browser/browser_process.h" |
-#include "components/network_time/network_time_tracker.h" |
+#include "chrome/browser/chrome_notification_types.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "content/public/browser/notification_service.h" |
+#include "content/public/browser/web_contents.h" |
+#include "net/base/network_change_notifier.h" |
#include "net/cert/x509_certificate.h" |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+#include "chrome/browser/captive_portal/captive_portal_service.h" |
+#include "chrome/browser/captive_portal/captive_portal_service_factory.h" |
+#endif |
+ |
using base::Time; |
using base::TimeTicks; |
using base::TimeDelta; |
@@ -25,6 +34,23 @@ enum SSLInterstitialCause { |
UNUSED_INTERSTITIAL_CAUSE_ENTRY, |
}; |
+// Events for UMA. Do not reorder or change! |
+enum SSLBlockingPageCaptivePortal { |
felt
2014/07/18 23:53:42
SSLInterstitialCauseCaptivePortal maybe?
radhikabhar
2014/07/21 16:05:11
Done.
|
+ CAPTIVE_PORTAL_DETECTION_ENABLED, |
+ CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE, |
+ CAPTIVE_PORTAL_PROBE_COMPLETED, |
+ CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE, |
+ CAPTIVE_PORTAL_NO_RESPONSE, |
+ CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE, |
+ CAPTIVE_PORTAL_DETECTED, |
+ CAPTIVE_PORTAL_DETECTED_OVERRIDABLE, |
+ UNUSED_CAPTIVE_PORTAL_EVENT, |
+}; |
+ |
+// Scores/weights which will be constant through all the SSL error types. |
+static const float kServerWeight = 0.5f; |
+static const float kClientWeight = 0.5f; |
+ |
void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { |
if (overridable) { |
UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, |
@@ -35,36 +61,59 @@ void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { |
} |
} |
+void RecordCaptivePortalEventStats(SSLBlockingPageCaptivePortal event) { |
+ UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captiveportal", |
felt
2014/07/18 23:53:42
interstitial.ssl.captive_portal I think would be i
radhikabhar
2014/07/23 21:41:28
Done.
|
+ event, |
+ UNUSED_CAPTIVE_PORTAL_EVENT); |
+} |
+ |
} // namespace |
SSLErrorClassification::SSLErrorClassification( |
+ content::WebContents& web_contents, |
base::Time current_time, |
const net::X509Certificate& cert) |
- : current_time_(current_time), |
- cert_(cert) { } |
+ : web_contents_(web_contents), |
+ current_time_(current_time), |
+ cert_(cert), |
+ captive_portal_detection_enabled_(false), |
+ captive_portal_probe_completed_(false), |
+ captive_portal_no_response_(false), |
+ captive_portal_detected_(false) { |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+ Profile* profile = Profile::FromBrowserContext( |
+ web_contents_.GetBrowserContext()); |
+ CaptivePortalService* captive_portal_service = |
+ CaptivePortalServiceFactory::GetForProfile(profile); |
+ captive_portal_detection_enabled_ = captive_portal_service ->enabled(); |
+ captive_portal_service ->DetectCaptivePortal(); |
+ registrar_.Add(this, |
+ chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, |
+ content::Source<Profile>(profile)); |
+#endif |
+} |
SSLErrorClassification::~SSLErrorClassification() { } |
-float SSLErrorClassification::InvalidDateSeverityScore() const { |
- // Client-side characterisitics. Check whether the system's clock is wrong or |
- // not and whether the user has encountered this error before or not. |
+float SSLErrorClassification::InvalidDateSeverityScore() const{ |
+ // Client-side characteristics. Check whether or not the system's clock is |
+ // wrong and whether or not the user has already encountered this error |
+ // before. |
float severity_date_score = 0.0f; |
- static const float kClientWeight = 0.5f; |
+ static const float kCertificateExpiredWeight = 0.3f; |
+ static const float kNotYetValidWeight = 0.2f; |
+ |
static const float kSystemClockWeight = 0.75f; |
static const float kSystemClockWrongWeight = 0.1f; |
static const float kSystemClockRightWeight = 1.0f; |
- static const float kServerWeight = 0.5f; |
- static const float kCertificateExpiredWeight = 0.3f; |
- static const float kNotYetValidWeight = 0.2f; |
- |
if (IsUserClockInThePast(current_time_) || |
IsUserClockInTheFuture(current_time_)) { |
- severity_date_score = kClientWeight * kSystemClockWeight * |
+ severity_date_score += kClientWeight * kSystemClockWeight * |
kSystemClockWrongWeight; |
} else { |
- severity_date_score = kClientWeight * kSystemClockWeight * |
+ severity_date_score += kClientWeight * kSystemClockWeight * |
kSystemClockRightWeight; |
} |
// TODO(radhikabhar): (crbug.com/393262) Check website settings. |
@@ -81,6 +130,41 @@ float SSLErrorClassification::InvalidDateSeverityScore() const { |
return severity_date_score; |
} |
+void SSLErrorClassification::RecordUMAStatistics(bool overridable) { |
+ if (IsUserClockInThePast(base::Time::NowFromSystemTime())) |
+ RecordSSLInterstitialCause(overridable, CLOCK_PAST); |
+ if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) |
+ RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); |
+} |
+ |
+void SSLErrorClassification::RecordUMAStatisticsCaptivePortals( |
+ bool overridable) { |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+ if (captive_portal_detection_enabled_) |
+ RecordCaptivePortalEventStats( |
+ overridable ? |
+ CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE : |
+ CAPTIVE_PORTAL_DETECTION_ENABLED); |
+ if (captive_portal_probe_completed_) |
+ RecordCaptivePortalEventStats( |
+ overridable ? |
+ CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE : |
+ CAPTIVE_PORTAL_PROBE_COMPLETED); |
+ // Log only one of portal detected and no response results. |
+ if (captive_portal_detected_) |
+ RecordCaptivePortalEventStats( |
+ overridable ? |
+ CAPTIVE_PORTAL_DETECTED_OVERRIDABLE : |
+ CAPTIVE_PORTAL_DETECTED); |
+ else if (captive_portal_no_response_) |
+ RecordCaptivePortalEventStats( |
+ overridable ? |
+ CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE : |
+ CAPTIVE_PORTAL_NO_RESPONSE); |
+#endif |
+} |
+ |
+ |
base::TimeDelta SSLErrorClassification::TimePassedSinceExpiry() const { |
base::TimeDelta delta = current_time_ - cert_.valid_expiry(); |
return delta; |
@@ -102,6 +186,31 @@ float SSLErrorClassification::CalculateScoreTimePassedSinceExpiry() const { |
return kLowThresholdWeight; |
} |
+float SSLErrorClassification::CalculateScoreEnvironments() const { |
+ static const float kWifiWeight = 0.7f; |
+ static const float kCellularWeight = 0.7f; |
+ static const float kHotspotWeight = 0.2f; |
+ static const float kEthernetWeight = 0.7f; |
+ static const float kOtherWeight = 0.7f; |
+ net::NetworkChangeNotifier::ConnectionType type = |
+ net::NetworkChangeNotifier::GetConnectionType(); |
+ if (type == net::NetworkChangeNotifier::CONNECTION_WIFI) |
+ return kWifiWeight; |
+ if (type == net::NetworkChangeNotifier::CONNECTION_2G || |
+ type == net::NetworkChangeNotifier::CONNECTION_3G || |
+ type == net::NetworkChangeNotifier::CONNECTION_4G) |
meacer
2014/07/19 00:06:45
Multiline ifs should have braces {}
radhikabhar
2014/07/23 21:41:28
Done.
|
+ return kCellularWeight; |
+ if (type == net::NetworkChangeNotifier::CONNECTION_ETHERNET) |
+ return kEthernetWeight; |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+ // Assume if captive portals are detected then the user is connected using a |
+ // hot spot. |
+ if (captive_portal_detected_) |
+ return kHotspotWeight; |
+#endif |
+ return kOtherWeight; |
+} |
+ |
bool SSLErrorClassification::IsUserClockInThePast(base::Time time_now) { |
base::Time build_time = base::GetBuildTime(); |
if (time_now < build_time - base::TimeDelta::FromDays(2)) |
@@ -116,9 +225,34 @@ bool SSLErrorClassification::IsUserClockInTheFuture(base::Time time_now) { |
return false; |
} |
-void SSLErrorClassification::RecordUMAStatistics(bool overridable) { |
- if (IsUserClockInThePast(base::Time::NowFromSystemTime())) |
- RecordSSLInterstitialCause(overridable, CLOCK_PAST); |
- if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) |
- RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); |
+void SSLErrorClassification::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+ // When detection is disabled, captive portal service always sends |
+ // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case. |
+ if (!captive_portal_detection_enabled_) |
+ return; |
+ if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) { |
+ captive_portal_probe_completed_ = true; |
+ CaptivePortalService::Results* results = |
+ content::Details<CaptivePortalService::Results>( |
+ details).ptr(); |
+ // If a captive portal was detected at any point when the interstitial was |
+ // displayed, assume that the interstitial was caused by a captive portal. |
+ // Example scenario: |
+ // 1- Interstitial displayed and captive portal detected, setting the flag. |
+ // 2- Captive portal detection automatically opens portal login page. |
+ // 3- User logs in on the portal login page. |
+ // A notification will be received here for RESULT_INTERNET_CONNECTED. Make |
+ // sure we don't clear the captive protal flag, since the interstitial was |
+ // potentially caused by the captive portal. |
+ captive_portal_detected_ = captive_portal_detected_ || |
+ (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL); |
+ // Also keep track of non-HTTP portals and error cases. |
+ captive_portal_no_response_ = captive_portal_no_response_ || |
+ (results->result == captive_portal::RESULT_NO_RESPONSE); |
+ } |
+#endif |
} |