Index: chrome/browser/chromeos/net/network_portal_detector.cc |
diff --git a/chrome/browser/chromeos/net/network_portal_detector.cc b/chrome/browser/chromeos/net/network_portal_detector.cc |
index 4a2b6a51587106017b0ab5717962df32a21d13c4..372696b5d8b3541ecfb8a29a7d4a5fffc05454c8 100644 |
--- a/chrome/browser/chromeos/net/network_portal_detector.cc |
+++ b/chrome/browser/chromeos/net/network_portal_detector.cc |
@@ -38,6 +38,11 @@ const int kRequestTimeoutSec = 10; |
// Delay before portal detection caused by changes in proxy settings. |
const int kProxyChangeDelayMs = 500; |
+// Delay between consecutive portal checks for a network in lazy mode. |
+// TODO (ygorshenin@): use exponential backoff or normally distributed |
+// random variable instead of this. |
+const int kLazyCheckIntervalSec = 30; |
+ |
std::string CaptivePortalStatusString( |
NetworkPortalDetector::CaptivePortalStatus status) { |
switch (status) { |
@@ -73,6 +78,8 @@ NetworkPortalDetector::NetworkPortalDetector( |
test_url_(CaptivePortalDetector::kDefaultURL), |
weak_ptr_factory_(this), |
attempt_count_(0), |
+ lazy_detection_enabled_(false), |
+ lazy_check_interval_(base::TimeDelta::FromSeconds(kLazyCheckIntervalSec)), |
min_time_between_attempts_( |
base::TimeDelta::FromSeconds(kMinTimeBetweenAttemptsSec)), |
request_timeout_(base::TimeDelta::FromSeconds(kRequestTimeoutSec)) { |
@@ -170,18 +177,12 @@ void NetworkPortalDetector::OnNetworkManagerChanged(NetworkLibrary* cros) { |
if (network_changed || connection_state_changed) { |
attempt_count_ = 0; |
- if (IsPortalCheckPending()) { |
- detection_task_.Cancel(); |
- detection_timeout_.Cancel(); |
- } else if (IsCheckingForPortal()) { |
- captive_portal_detector_->Cancel(); |
- } |
- state_ = STATE_IDLE; |
+ CancelPortalDetection(); |
} |
if (!IsCheckingForPortal() && !IsPortalCheckPending() && |
Network::IsConnectedState(active_connection_state_) && |
- attempt_count_ < kMaxRequestAttempts) { |
+ (attempt_count_ < kMaxRequestAttempts || lazy_detection_enabled_)) { |
DCHECK(active_network); |
// Initiate Captive Portal detection if network's captive |
@@ -202,6 +203,24 @@ void NetworkPortalDetector::OnNetworkChanged(chromeos::NetworkLibrary* cros, |
OnNetworkManagerChanged(cros); |
} |
+void NetworkPortalDetector::EnableLazyDetection() { |
+ if (lazy_detection_enabled_) |
+ return; |
+ VLOG(1) << "Lazy detection mode enabled"; |
+ lazy_detection_enabled_ = true; |
+ if (!IsPortalCheckPending() && !IsCheckingForPortal()) |
+ DetectCaptivePortal(base::TimeDelta()); |
+} |
+ |
+void NetworkPortalDetector::DisableLazyDetection() { |
+ if (!lazy_detection_enabled_) |
+ return; |
+ VLOG(1) << "Lazy detection mode disabled"; |
+ if (attempt_count_ == kMaxRequestAttempts) |
+ CancelPortalDetection(); |
+ lazy_detection_enabled_ = false; |
+} |
+ |
// static |
NetworkPortalDetector* NetworkPortalDetector::CreateInstance() { |
DCHECK(!g_network_portal_detector); |
@@ -226,7 +245,7 @@ bool NetworkPortalDetector::IsEnabled() { |
void NetworkPortalDetector::DetectCaptivePortal(const base::TimeDelta& delay) { |
DCHECK(!IsPortalCheckPending()); |
DCHECK(!IsCheckingForPortal()); |
- DCHECK(attempt_count_ < kMaxRequestAttempts); |
+ DCHECK(attempt_count_ < kMaxRequestAttempts || lazy_detection_enabled_); |
detection_task_.Cancel(); |
detection_timeout_.Cancel(); |
@@ -236,11 +255,17 @@ void NetworkPortalDetector::DetectCaptivePortal(const base::TimeDelta& delay) { |
if (attempt_count_ > 0) { |
base::TimeTicks now = GetCurrentTimeTicks(); |
base::TimeDelta elapsed_time; |
+ |
+ base::TimeDelta delay_between_attempts = min_time_between_attempts_; |
+ if (attempt_count_ == kMaxRequestAttempts) { |
+ DCHECK(lazy_detection_enabled_); |
+ delay_between_attempts = lazy_check_interval_; |
+ } |
if (now > attempt_start_time_) |
elapsed_time = now - attempt_start_time_; |
- if (elapsed_time < min_time_between_attempts_ && |
- min_time_between_attempts_ - elapsed_time > next_attempt_delay_) { |
- next_attempt_delay_ = min_time_between_attempts_ - elapsed_time; |
+ if (elapsed_time < delay_between_attempts && |
+ delay_between_attempts - elapsed_time > next_attempt_delay_) { |
+ next_attempt_delay_ = delay_between_attempts - elapsed_time; |
} |
} else { |
detection_start_time_ = GetCurrentTimeTicks(); |
@@ -258,11 +283,17 @@ void NetworkPortalDetector::DetectCaptivePortalTask() { |
state_ = STATE_CHECKING_FOR_PORTAL; |
- ++attempt_count_; |
attempt_start_time_ = GetCurrentTimeTicks(); |
- VLOG(1) << "Portal detection started: network=" << active_network_id_ << ", " |
- << "attempt=" << attempt_count_ << " of " << kMaxRequestAttempts; |
+ if (attempt_count_ < kMaxRequestAttempts) { |
+ ++attempt_count_; |
+ VLOG(1) << "Portal detection started: " |
+ << "network=" << active_network_id_ << ", " |
+ << "attempt=" << attempt_count_ << " of " << kMaxRequestAttempts; |
+ } else { |
+ DCHECK(lazy_detection_enabled_); |
+ VLOG(1) << "Lazy portal detection attempt started"; |
+ } |
captive_portal_detector_->DetectCaptivePortal( |
test_url_, |
@@ -288,6 +319,16 @@ void NetworkPortalDetector::PortalDetectionTimeout() { |
OnPortalDetectionCompleted(results); |
} |
+void NetworkPortalDetector::CancelPortalDetection() { |
+ if (IsPortalCheckPending()) { |
+ detection_task_.Cancel(); |
+ detection_timeout_.Cancel(); |
+ } else if (IsCheckingForPortal()) { |
+ captive_portal_detector_->Cancel(); |
+ } |
+ state_ = STATE_IDLE; |
+} |
+ |
void NetworkPortalDetector::OnPortalDetectionCompleted( |
const CaptivePortalDetector::Results& results) { |
DCHECK(CalledOnValidThread()); |
@@ -304,8 +345,10 @@ void NetworkPortalDetector::OnPortalDetectionCompleted( |
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
const Network* active_network = cros->active_network(); |
- if (!active_network) |
+ if (!active_network) { |
+ TryLazyDetection(); |
return; |
+ } |
CaptivePortalState state; |
state.response_code = results.response_code; |
@@ -342,7 +385,18 @@ void NetworkPortalDetector::OnPortalDetectionCompleted( |
default: |
break; |
} |
+ |
+ TryLazyDetection(); |
} |
+ |
+void NetworkPortalDetector::TryLazyDetection() { |
+ if (!IsPortalCheckPending() && !IsCheckingForPortal() && |
+ lazy_detection_enabled_) { |
+ attempt_count_ = kMaxRequestAttempts; |
+ DetectCaptivePortal(base::TimeDelta()); |
+ } |
+} |
+ |
void NetworkPortalDetector::Observe( |
int type, |
const content::NotificationSource& source, |