Index: chrome/browser/ssl/captive_portal_metrics_recorder.cc |
diff --git a/chrome/browser/ssl/captive_portal_metrics_recorder.cc b/chrome/browser/ssl/captive_portal_metrics_recorder.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4f8473f1a85ced7084787742f9847f27af1a3752 |
--- /dev/null |
+++ b/chrome/browser/ssl/captive_portal_metrics_recorder.cc |
@@ -0,0 +1,120 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/ssl/captive_portal_metrics_recorder.h" |
+ |
+#include <vector> |
+ |
+#include "base/metrics/histogram_macros.h" |
+#include "chrome/browser/browser_process.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" |
+ |
+#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 |
+ |
+namespace { |
+ |
+// Events for UMA. Do not reorder or change! |
+enum SSLInterstitialCauseCaptivePortal { |
+ CAPTIVE_PORTAL_ALL, |
+ 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, |
+}; |
+ |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) { |
+ UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal", event, |
+ UNUSED_CAPTIVE_PORTAL_EVENT); |
+} |
+#endif |
+ |
+} // namespace |
+ |
+CaptivePortalMetricsRecorder::CaptivePortalMetricsRecorder( |
+ content::WebContents* web_contents, |
+ bool overridable) |
+ : 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) |
+ overridable_ = overridable; |
+ Profile* profile = |
+ Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
+ captive_portal_detection_enabled_ = |
+ CaptivePortalServiceFactory::GetForProfile(profile)->enabled(); |
+ registrar_.Add(this, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, |
+ content::Source<Profile>(profile)); |
+#endif |
+} |
+ |
+CaptivePortalMetricsRecorder::~CaptivePortalMetricsRecorder() {} |
+ |
+void CaptivePortalMetricsRecorder::RecordCaptivePortalUMAStatistics() const { |
+#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
+ RecordCaptivePortalEventStats(CAPTIVE_PORTAL_ALL); |
+ 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 |
+} |
+ |
+void CaptivePortalMetricsRecorder::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 |
+} |