1 // Copyright 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/chromeos/net/network_portal_detector_strategy.h" 6 7 #include "base/logging.h" 8 #include "chromeos/network/network_handler.h" 9 #include "chromeos/network/network_state.h" 10 #include "chromeos/network/network_state_handler.h" 11 12 namespace chromeos { 13 14 namespace { 15 DefaultNetwork()16const NetworkState* DefaultNetwork() { 17 return NetworkHandler::Get()->network_state_handler()->DefaultNetwork(); 18 } 19 20 // TODO (ygorshenin@): reuse net::BackoffEntry for strategies. 21 22 class LoginScreenStrategy : public PortalDetectorStrategy { 23 public: 24 static const int kMaxAttempts = 3; 25 static const int kDelayBetweenAttemptsSec = 3; 26 static const int kBaseAttemptTimeoutSec = 5; 27 LoginScreenStrategy()28 LoginScreenStrategy() {} ~LoginScreenStrategy()29 virtual ~LoginScreenStrategy() {} 30 31 protected: 32 // PortalDetectorStrategy overrides: Id() const33 virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_LOGIN_SCREEN; } CanPerformAttemptImpl()34 virtual bool CanPerformAttemptImpl() OVERRIDE { 35 return delegate_->AttemptCount() < kMaxAttempts; 36 } GetDelayTillNextAttemptImpl()37 virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE { 38 return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec)); 39 } GetNextAttemptTimeoutImpl()40 virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE { 41 int timeout = DefaultNetwork() 42 ? (delegate_->AttemptCount() + 1) * kBaseAttemptTimeoutSec 43 : kBaseAttemptTimeoutSec; 44 return base::TimeDelta::FromSeconds(timeout); 45 } 46 47 private: 48 DISALLOW_COPY_AND_ASSIGN(LoginScreenStrategy); 49 }; 50 51 class ErrorScreenStrategy : public PortalDetectorStrategy { 52 public: 53 static const int kDelayBetweenAttemptsSec = 3; 54 static const int kAttemptTimeoutSec = 15; 55 ErrorScreenStrategy()56 ErrorScreenStrategy() {} ~ErrorScreenStrategy()57 virtual ~ErrorScreenStrategy() {} 58 59 protected: 60 // PortalDetectorStrategy overrides: Id() const61 virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_ERROR_SCREEN; } CanPerformAttemptImpl()62 virtual bool CanPerformAttemptImpl() OVERRIDE { return true; } CanPerformAttemptAfterDetectionImpl()63 virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; } GetDelayTillNextAttemptImpl()64 virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE { 65 return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec)); 66 } GetNextAttemptTimeoutImpl()67 virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE { 68 return base::TimeDelta::FromSeconds(kAttemptTimeoutSec); 69 } 70 71 private: 72 DISALLOW_COPY_AND_ASSIGN(ErrorScreenStrategy); 73 }; 74 75 class SessionStrategy : public PortalDetectorStrategy { 76 public: 77 static const int kFastDelayBetweenAttemptsSec = 1; 78 static const int kFastAttemptTimeoutSec = 3; 79 static const int kMaxFastAttempts = 3; 80 81 static const int kNormalDelayBetweenAttemptsSec = 10; 82 static const int kNormalAttemptTimeoutSec = 5; 83 static const int kMaxNormalAttempts = 3; 84 85 static const int kSlowDelayBetweenAttemptsSec = 2 * 60; 86 static const int kSlowAttemptTimeoutSec = 5; 87 SessionStrategy()88 SessionStrategy() {} ~SessionStrategy()89 virtual ~SessionStrategy() {} 90 91 protected: Id() const92 virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_SESSION; } CanPerformAttemptImpl()93 virtual bool CanPerformAttemptImpl() OVERRIDE { return true; } CanPerformAttemptAfterDetectionImpl()94 virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; } GetDelayTillNextAttemptImpl()95 virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE { 96 int delay; 97 if (IsFastAttempt()) 98 delay = kFastDelayBetweenAttemptsSec; 99 else if (IsNormalAttempt()) 100 delay = kNormalDelayBetweenAttemptsSec; 101 else 102 delay = kSlowDelayBetweenAttemptsSec; 103 return AdjustDelay(base::TimeDelta::FromSeconds(delay)); 104 } GetNextAttemptTimeoutImpl()105 virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE { 106 int timeout; 107 if (IsFastAttempt()) 108 timeout = kFastAttemptTimeoutSec; 109 else if (IsNormalAttempt()) 110 timeout = kNormalAttemptTimeoutSec; 111 else 112 timeout = kSlowAttemptTimeoutSec; 113 return base::TimeDelta::FromSeconds(timeout); 114 } 115 116 private: IsFastAttempt()117 bool IsFastAttempt() { 118 return delegate_->AttemptCount() < kMaxFastAttempts; 119 } 120 IsNormalAttempt()121 bool IsNormalAttempt() { 122 return delegate_->AttemptCount() < kMaxFastAttempts + kMaxNormalAttempts; 123 } 124 125 DISALLOW_COPY_AND_ASSIGN(SessionStrategy); 126 }; 127 128 } // namespace 129 130 // PortalDetectorStrategy ----------------------------------------------------- 131 132 // static 133 base::TimeDelta PortalDetectorStrategy::delay_till_next_attempt_for_testing_; 134 135 // static 136 bool PortalDetectorStrategy::delay_till_next_attempt_for_testing_initialized_ = 137 false; 138 139 // static 140 base::TimeDelta PortalDetectorStrategy::next_attempt_timeout_for_testing_; 141 142 // static 143 bool PortalDetectorStrategy::next_attempt_timeout_for_testing_initialized_ = 144 false; 145 PortalDetectorStrategy()146PortalDetectorStrategy::PortalDetectorStrategy() : delegate_(NULL) {} 147 ~PortalDetectorStrategy()148PortalDetectorStrategy::~PortalDetectorStrategy() {} 149 150 // statc CreateById(StrategyId id)151scoped_ptr<PortalDetectorStrategy> PortalDetectorStrategy::CreateById( 152 StrategyId id) { 153 switch (id) { 154 case STRATEGY_ID_LOGIN_SCREEN: 155 return scoped_ptr<PortalDetectorStrategy>(new LoginScreenStrategy()); 156 case STRATEGY_ID_ERROR_SCREEN: 157 return scoped_ptr<PortalDetectorStrategy>(new ErrorScreenStrategy()); 158 case STRATEGY_ID_SESSION: 159 return scoped_ptr<PortalDetectorStrategy>(new SessionStrategy()); 160 default: 161 NOTREACHED(); 162 return scoped_ptr<PortalDetectorStrategy>( 163 static_cast<PortalDetectorStrategy*>(NULL)); 164 } 165 } 166 CanPerformAttempt()167bool PortalDetectorStrategy::CanPerformAttempt() { 168 return CanPerformAttemptImpl(); 169 } 170 CanPerformAttemptAfterDetection()171bool PortalDetectorStrategy::CanPerformAttemptAfterDetection() { 172 return CanPerformAttemptAfterDetectionImpl(); 173 } 174 GetDelayTillNextAttempt()175base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttempt() { 176 if (delay_till_next_attempt_for_testing_initialized_) 177 return delay_till_next_attempt_for_testing_; 178 return GetDelayTillNextAttemptImpl(); 179 } 180 GetNextAttemptTimeout()181base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeout() { 182 if (next_attempt_timeout_for_testing_initialized_) 183 return next_attempt_timeout_for_testing_; 184 return GetNextAttemptTimeoutImpl(); 185 } 186 CanPerformAttemptImpl()187bool PortalDetectorStrategy::CanPerformAttemptImpl() { return false; } 188 CanPerformAttemptAfterDetectionImpl()189bool PortalDetectorStrategy::CanPerformAttemptAfterDetectionImpl() { 190 return false; 191 } 192 GetDelayTillNextAttemptImpl()193base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttemptImpl() { 194 return base::TimeDelta(); 195 } 196 GetNextAttemptTimeoutImpl()197base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeoutImpl() { 198 return base::TimeDelta(); 199 } 200 AdjustDelay(const base::TimeDelta & delay)201base::TimeDelta PortalDetectorStrategy::AdjustDelay( 202 const base::TimeDelta& delay) { 203 if (!delegate_->AttemptCount()) 204 return base::TimeDelta(); 205 206 base::TimeTicks now = delegate_->GetCurrentTimeTicks(); 207 base::TimeDelta elapsed; 208 if (now > delegate_->AttemptStartTime()) 209 elapsed = now - delegate_->AttemptStartTime(); 210 if (delay > elapsed) 211 return delay - elapsed; 212 return base::TimeDelta(); 213 } 214 215 } // namespace chromeos 216