Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2013 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 #ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
      6 #define CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/cancelable_callback.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/containers/hash_tables.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/observer_list.h"
     18 #include "base/threading/non_thread_safe.h"
     19 #include "base/time/time.h"
     20 #include "chrome/browser/captive_portal/captive_portal_detector.h"
     21 #include "chrome/browser/chromeos/net/network_portal_detector.h"
     22 #include "chromeos/network/network_state_handler_observer.h"
     23 #include "content/public/browser/notification_observer.h"
     24 #include "content/public/browser/notification_registrar.h"
     25 #include "net/url_request/url_fetcher.h"
     26 #include "url/gurl.h"
     27 
     28 namespace net {
     29 class URLRequestContextGetter;
     30 }
     31 
     32 namespace chromeos {
     33 
     34 class NetworkState;
     35 
     36 // This class handles all notifications about network changes from
     37 // NetworkLibrary and delegates portal detection for the default
     38 // network to CaptivePortalService.
     39 class NetworkPortalDetectorImpl
     40     : public NetworkPortalDetector,
     41       public base::NonThreadSafe,
     42       public chromeos::NetworkStateHandlerObserver,
     43       public content::NotificationObserver {
     44  public:
     45   explicit NetworkPortalDetectorImpl(
     46       const scoped_refptr<net::URLRequestContextGetter>& request_context);
     47   virtual ~NetworkPortalDetectorImpl();
     48 
     49   // NetworkPortalDetector implementation:
     50   virtual void Init() OVERRIDE;
     51   virtual void Shutdown() OVERRIDE;
     52   virtual void AddObserver(Observer* observer) OVERRIDE;
     53   virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
     54   virtual void RemoveObserver(Observer* observer) OVERRIDE;
     55   virtual CaptivePortalState GetCaptivePortalState(
     56       const chromeos::NetworkState* network) OVERRIDE;
     57   virtual bool IsEnabled() OVERRIDE;
     58   virtual void Enable(bool start_detection) OVERRIDE;
     59   virtual bool StartDetectionIfIdle() OVERRIDE;
     60   virtual void EnableLazyDetection() OVERRIDE;
     61   virtual void DisableLazyDetection() OVERRIDE;
     62 
     63   // NetworkStateHandlerObserver implementation:
     64   virtual void NetworkManagerChanged() OVERRIDE;
     65   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
     66 
     67  private:
     68   friend class NetworkPortalDetectorImplTest;
     69 
     70   typedef std::string NetworkId;
     71   typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
     72 
     73   enum State {
     74     // No portal check is running.
     75     STATE_IDLE = 0,
     76     // Waiting for portal check.
     77     STATE_PORTAL_CHECK_PENDING,
     78     // Portal check is in progress.
     79     STATE_CHECKING_FOR_PORTAL,
     80   };
     81 
     82   // Basic unit used in detection timeout computation.
     83   static const int kBaseRequestTimeoutSec = 5;
     84 
     85   // Single detection attempt timeout in lazy mode.
     86   static const int kLazyRequestTimeoutSec = 15;
     87 
     88   // Internal predicate which describes set of states from which
     89   // DetectCaptivePortal() can be called.
     90   bool CanPerformDetection() const;
     91 
     92   // Initiates Captive Portal detection after |delay|.
     93   // CanPerformDetection() *must* be kept before call to this method.
     94   void DetectCaptivePortal(const base::TimeDelta& delay);
     95 
     96   void DetectCaptivePortalTask();
     97 
     98   // Called when portal check is timed out. Cancels portal check and
     99   // calls OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as
    100   // a result.
    101   void PortalDetectionTimeout();
    102 
    103   void CancelPortalDetection();
    104 
    105   // Called by CaptivePortalDetector when detection completes.
    106   void OnPortalDetectionCompleted(
    107       const captive_portal::CaptivePortalDetector::Results& results);
    108 
    109   // Tries to perform portal detection in "lazy" mode. Does nothing in
    110   // the case of already pending/processing detection request.
    111   void TryLazyDetection();
    112 
    113   // content::NotificationObserver implementation:
    114   virtual void Observe(int type,
    115                        const content::NotificationSource& source,
    116                        const content::NotificationDetails& details) OVERRIDE;
    117 
    118   // Returns true if we're waiting for portal check.
    119   bool IsPortalCheckPending() const;
    120 
    121   // Returns true if portal check is in progress.
    122   bool IsCheckingForPortal() const;
    123 
    124   // Stores captive portal state for a |network|.
    125   void SetCaptivePortalState(const NetworkState* network,
    126                              const CaptivePortalState& results);
    127 
    128   // Notifies observers that portal detection is completed for a |network|.
    129   void NotifyPortalDetectionCompleted(const NetworkState* network,
    130                                       const CaptivePortalState& state);
    131 
    132   // Returns the current TimeTicks.
    133   base::TimeTicks GetCurrentTimeTicks() const;
    134 
    135   State state() const { return state_; }
    136 
    137   bool lazy_detection_enabled() const { return lazy_detection_enabled_; }
    138 
    139   // Returns current number of portal detection attempts.
    140   // Used by unit tests.
    141   int attempt_count_for_testing() const { return attempt_count_; }
    142 
    143   // Sets current number of detection attempts.
    144   // Used by unit tests.
    145   void set_attempt_count_for_testing(int attempt_count) {
    146     attempt_count_ = attempt_count;
    147   }
    148 
    149   // Sets minimum time between consecutive portal checks for the same
    150   // network. Used by unit tests.
    151   void set_min_time_between_attempts_for_testing(const base::TimeDelta& delta) {
    152     min_time_between_attempts_ = delta;
    153   }
    154 
    155   // Sets default interval between consecutive portal checks for a
    156   // network in portal state. Used by unit tests.
    157   void set_lazy_check_interval_for_testing(const base::TimeDelta& delta) {
    158     lazy_check_interval_ = delta;
    159   }
    160 
    161   // Sets portal detection timeout. Used by unit tests.
    162   void set_request_timeout_for_testing(const base::TimeDelta& timeout) {
    163     request_timeout_for_testing_ = timeout;
    164     request_timeout_for_testing_initialized_ = true;
    165   }
    166 
    167   // Returns delay before next portal check. Used by unit tests.
    168   const base::TimeDelta& next_attempt_delay_for_testing() const {
    169     return next_attempt_delay_;
    170   }
    171 
    172   // Sets current test time ticks. Used by unit tests.
    173   void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
    174     time_ticks_for_testing_ = time_ticks;
    175   }
    176 
    177   // Advances current test time ticks. Used by unit tests.
    178   void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
    179     time_ticks_for_testing_ += delta;
    180   }
    181 
    182   // Returns true if detection timeout callback isn't fired or
    183   // cancelled.
    184   bool DetectionTimeoutIsCancelledForTesting() const;
    185 
    186   // Returns timeout for current (or immediate) detection attempt.
    187   // The following rules are used for timeout computation:
    188   // * if default (active) network is NULL, kBaseRequestTimeoutSec is used
    189   // * if lazy detection mode is enabled, kLazyRequestTimeoutSec is used
    190   // * otherwise, timeout equals to |attempt_count_| * kBaseRequestTimeoutSec
    191   int GetRequestTimeoutSec() const;
    192 
    193   // Unique identifier of the default network.
    194   std::string default_network_id_;
    195 
    196   // Service path of the default network.
    197   std::string default_service_path_;
    198 
    199   // Connection state of the default network.
    200   std::string default_connection_state_;
    201 
    202   State state_;
    203   CaptivePortalStateMap portal_state_map_;
    204   ObserverList<Observer> observers_;
    205 
    206   base::CancelableClosure detection_task_;
    207   base::CancelableClosure detection_timeout_;
    208 
    209   // URL that returns a 204 response code when connected to the Internet.
    210   GURL test_url_;
    211 
    212   // Detector for checking default network for a portal state.
    213   scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
    214 
    215   // True if the NetworkPortalDetector is enabled.
    216   bool enabled_;
    217 
    218   base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_ptr_factory_;
    219 
    220   // Number of portal detection attemps for a default network.
    221   int attempt_count_;
    222 
    223   bool lazy_detection_enabled_;
    224 
    225   // Time between consecutive portal checks for a network in lazy
    226   // mode.
    227   base::TimeDelta lazy_check_interval_;
    228 
    229   // Minimum time between consecutive portal checks for the same
    230   // default network.
    231   base::TimeDelta min_time_between_attempts_;
    232 
    233   // Start time of portal detection.
    234   base::TimeTicks detection_start_time_;
    235 
    236   // Start time of portal detection attempt.
    237   base::TimeTicks attempt_start_time_;
    238 
    239   // Delay before next portal detection.
    240   base::TimeDelta next_attempt_delay_;
    241 
    242   // Test time ticks used by unit tests.
    243   base::TimeTicks time_ticks_for_testing_;
    244 
    245   // Test timeout for a portal detection used by unit tests.
    246   base::TimeDelta request_timeout_for_testing_;
    247 
    248   // True if |request_timeout_for_testing_| is initialized.
    249   bool request_timeout_for_testing_initialized_;
    250 
    251   content::NotificationRegistrar registrar_;
    252 
    253   DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
    254 };
    255 
    256 }  // namespace chromeos
    257 
    258 #endif  // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
    259