network_portal_detector_strategy.cc revision 116680a4aac90f2aa7413d9095a592090648e557
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_handler.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state_handler.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const NetworkState* DefaultNetwork() {
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO (ygorshenin@): reuse net::BackoffEntry for strategies.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LoginScreenStrategy : public PortalDetectorStrategy {
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxAttempts = 3;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDelayBetweenAttemptsSec = 3;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kBaseAttemptTimeoutSec = 5;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginScreenStrategy() {}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LoginScreenStrategy() {}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PortalDetectorStrategy overrides:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_LOGIN_SCREEN; }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanPerformAttemptImpl() OVERRIDE {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delegate_->AttemptCount() < kMaxAttempts;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int timeout = DefaultNetwork()
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      ? (delegate_->AttemptCount() + 1) * kBaseAttemptTimeoutSec
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      : kBaseAttemptTimeoutSec;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta::FromSeconds(timeout);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LoginScreenStrategy);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ErrorScreenStrategy : public PortalDetectorStrategy {
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  static const int kDelayBetweenAttemptsSec = 3;
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  static const int kAttemptTimeoutSec = 15;
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ErrorScreenStrategy() {}
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual ~ErrorScreenStrategy() {}
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PortalDetectorStrategy overrides:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_ERROR_SCREEN; }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanPerformAttemptImpl() OVERRIDE { return true; }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return AdjustDelay(base::TimeDelta::FromSeconds(kDelayBetweenAttemptsSec));
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::TimeDelta::FromSeconds(kAttemptTimeoutSec);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ErrorScreenStrategy);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionStrategy : public PortalDetectorStrategy {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kFastDelayBetweenAttemptsSec = 1;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kFastAttemptTimeoutSec = 3;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxFastAttempts = 3;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNormalDelayBetweenAttemptsSec = 10;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNormalAttemptTimeoutSec = 5;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxNormalAttempts = 3;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSlowDelayBetweenAttemptsSec = 2 * 60;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSlowAttemptTimeoutSec = 5;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionStrategy() {}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SessionStrategy() {}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual StrategyId Id() const OVERRIDE { return STRATEGY_ID_SESSION; }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanPerformAttemptImpl() OVERRIDE { return true; }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanPerformAttemptAfterDetectionImpl() OVERRIDE { return true; }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta GetDelayTillNextAttemptImpl() OVERRIDE {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int delay;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsFastAttempt())
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delay = kFastDelayBetweenAttemptsSec;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (IsNormalAttempt())
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay = kNormalDelayBetweenAttemptsSec;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay = kSlowDelayBetweenAttemptsSec;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return AdjustDelay(base::TimeDelta::FromSeconds(delay));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::TimeDelta GetNextAttemptTimeoutImpl() OVERRIDE {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int timeout;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsFastAttempt())
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timeout = kFastAttemptTimeoutSec;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (IsNormalAttempt())
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      timeout = kNormalAttemptTimeoutSec;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timeout = kSlowAttemptTimeoutSec;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta::FromSeconds(timeout);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsFastAttempt() {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delegate_->AttemptCount() < kMaxFastAttempts;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsNormalAttempt() {
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return delegate_->AttemptCount() < kMaxFastAttempts + kMaxNormalAttempts;
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SessionStrategy);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PortalDetectorStrategy -----------------------------------------------------
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::delay_till_next_attempt_for_testing_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PortalDetectorStrategy::delay_till_next_attempt_for_testing_initialized_ =
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::next_attempt_timeout_for_testing_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PortalDetectorStrategy::next_attempt_timeout_for_testing_initialized_ =
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    false;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PortalDetectorStrategy::PortalDetectorStrategy() : delegate_(NULL) {}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PortalDetectorStrategy::~PortalDetectorStrategy() {}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// statc
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<PortalDetectorStrategy> PortalDetectorStrategy::CreateById(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StrategyId id) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (id) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STRATEGY_ID_LOGIN_SCREEN:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return scoped_ptr<PortalDetectorStrategy>(new LoginScreenStrategy());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STRATEGY_ID_ERROR_SCREEN:
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return scoped_ptr<PortalDetectorStrategy>(new ErrorScreenStrategy());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STRATEGY_ID_SESSION:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return scoped_ptr<PortalDetectorStrategy>(new SessionStrategy());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return scoped_ptr<PortalDetectorStrategy>(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<PortalDetectorStrategy*>(NULL));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PortalDetectorStrategy::CanPerformAttempt() {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CanPerformAttemptImpl();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PortalDetectorStrategy::CanPerformAttemptAfterDetection() {
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return CanPerformAttemptAfterDetectionImpl();
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttempt() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delay_till_next_attempt_for_testing_initialized_)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delay_till_next_attempt_for_testing_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDelayTillNextAttemptImpl();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeout() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (next_attempt_timeout_for_testing_initialized_)
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return next_attempt_timeout_for_testing_;
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return GetNextAttemptTimeoutImpl();
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool PortalDetectorStrategy::CanPerformAttemptImpl() { return false; }
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool PortalDetectorStrategy::CanPerformAttemptAfterDetectionImpl() {
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return false;
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::GetDelayTillNextAttemptImpl() {
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return base::TimeDelta();
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta PortalDetectorStrategy::GetNextAttemptTimeoutImpl() {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::TimeDelta();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta PortalDetectorStrategy::AdjustDelay(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::TimeDelta& delay) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  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