• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()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 
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()146 PortalDetectorStrategy::PortalDetectorStrategy() : delegate_(NULL) {}
147 
~PortalDetectorStrategy()148 PortalDetectorStrategy::~PortalDetectorStrategy() {}
149 
150 // statc
CreateById(StrategyId id)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 
CanPerformAttempt()167 bool PortalDetectorStrategy::CanPerformAttempt() {
168   return CanPerformAttemptImpl();
169 }
170 
CanPerformAttemptAfterDetection()171 bool PortalDetectorStrategy::CanPerformAttemptAfterDetection() {
172   return CanPerformAttemptAfterDetectionImpl();
173 }
174 
GetDelayTillNextAttempt()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 
GetNextAttemptTimeout()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 
CanPerformAttemptImpl()187 bool PortalDetectorStrategy::CanPerformAttemptImpl() { return false; }
188 
CanPerformAttemptAfterDetectionImpl()189 bool PortalDetectorStrategy::CanPerformAttemptAfterDetectionImpl() {
190   return false;
191 }
192 
GetDelayTillNextAttemptImpl()193 base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttemptImpl() {
194   return base::TimeDelta();
195 }
196 
GetNextAttemptTimeoutImpl()197 base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeoutImpl() {
198   return base::TimeDelta();
199 }
200 
AdjustDelay(const base::TimeDelta & delay)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