Home | History | Annotate | Download | only in net
      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 
     16 const 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 
     28   LoginScreenStrategy() {}
     29   virtual ~LoginScreenStrategy() {}
     30 
     31  protected:
     32   // PortalDetectorStrategy overrides:
     33   virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_LOGIN_SCREEN; }
     34   virtual bool CanPerformAttemptImpl() OVERRIDE {
     35     return delegate_->AttemptCount() < kMaxAttempts;
     36   }
     37   virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE {
     38     return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec));
     39   }
     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 
     56   ErrorScreenStrategy() {}
     57   virtual ~ErrorScreenStrategy() {}
     58 
     59  protected:
     60   // PortalDetectorStrategy overrides:
     61   virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_ERROR_SCREEN; }
     62   virtual bool CanPerformAttemptImpl() OVERRIDE { return true; }
     63   virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; }
     64   virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE {
     65     return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec));
     66   }
     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 
     88   SessionStrategy() {}
     89   virtual ~SessionStrategy() {}
     90 
     91  protected:
     92   virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_SESSION; }
     93   virtual bool CanPerformAttemptImpl() OVERRIDE { return true; }
     94   virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; }
     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   }
    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:
    117   bool IsFastAttempt() {
    118     return delegate_->AttemptCount() < kMaxFastAttempts;
    119   }
    120 
    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 
    146 PortalDetectorStrategy::PortalDetectorStrategy() : delegate_(NULL) {}
    147 
    148 PortalDetectorStrategy::~PortalDetectorStrategy() {}
    149 
    150 // statc
    151 scoped_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 
    167 bool PortalDetectorStrategy::CanPerformAttempt() {
    168   return CanPerformAttemptImpl();
    169 }
    170 
    171 bool PortalDetectorStrategy::CanPerformAttemptAfterDetection() {
    172   return CanPerformAttemptAfterDetectionImpl();
    173 }
    174 
    175 base::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 
    181 base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeout() {
    182   if (next_attempt_timeout_for_testing_initialized_)
    183     return next_attempt_timeout_for_testing_;
    184   return GetNextAttemptTimeoutImpl();
    185 }
    186 
    187 bool PortalDetectorStrategy::CanPerformAttemptImpl() { return false; }
    188 
    189 bool PortalDetectorStrategy::CanPerformAttemptAfterDetectionImpl() {
    190   return false;
    191 }
    192 
    193 base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttemptImpl() {
    194   return base::TimeDelta();
    195 }
    196 
    197 base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeoutImpl() {
    198   return base::TimeDelta();
    199 }
    200 
    201 base::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