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/chromeos/net/network_portal_notification_controller.h"
     21 #include "chromeos/network/network_state_handler_observer.h"
     22 #include "chromeos/network/portal_detector/network_portal_detector.h"
     23 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
     24 #include "components/captive_portal/captive_portal_detector.h"
     25 #include "components/captive_portal/captive_portal_types.h"
     26 #include "content/public/browser/notification_observer.h"
     27 #include "content/public/browser/notification_registrar.h"
     28 #include "net/url_request/url_fetcher.h"
     29 #include "url/gurl.h"
     30 
     31 namespace net {
     32 class URLRequestContextGetter;
     33 }
     34 
     35 namespace chromeos {
     36 
     37 class NetworkState;
     38 
     39 // This class handles all notifications about network changes from
     40 // NetworkStateHandler and delegates portal detection for the default
     41 // network to CaptivePortalService.
     42 class NetworkPortalDetectorImpl
     43     : public NetworkPortalDetector,
     44       public base::NonThreadSafe,
     45       public chromeos::NetworkStateHandlerObserver,
     46       public content::NotificationObserver,
     47       public PortalDetectorStrategy::Delegate {
     48  public:
     49   static const char kOobeDetectionResultHistogram[];
     50   static const char kOobeDetectionDurationHistogram[];
     51   static const char kOobeShillOnlineHistogram[];
     52   static const char kOobeShillPortalHistogram[];
     53   static const char kOobeShillOfflineHistogram[];
     54   static const char kOobePortalToOnlineHistogram[];
     55 
     56   static const char kSessionDetectionResultHistogram[];
     57   static const char kSessionDetectionDurationHistogram[];
     58   static const char kSessionShillOnlineHistogram[];
     59   static const char kSessionShillPortalHistogram[];
     60   static const char kSessionShillOfflineHistogram[];
     61   static const char kSessionPortalToOnlineHistogram[];
     62 
     63   // Creates an instance of NetworkPortalDetectorImpl.
     64   static void Initialize(net::URLRequestContextGetter* url_context);
     65 
     66   explicit NetworkPortalDetectorImpl(
     67       const scoped_refptr<net::URLRequestContextGetter>& request_context);
     68   virtual ~NetworkPortalDetectorImpl();
     69 
     70   // NetworkPortalDetector implementation:
     71   virtual void AddObserver(Observer* observer) OVERRIDE;
     72   virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
     73   virtual void RemoveObserver(Observer* observer) OVERRIDE;
     74   virtual CaptivePortalState GetCaptivePortalState(
     75       const std::string& guid) OVERRIDE;
     76   virtual bool IsEnabled() OVERRIDE;
     77   virtual void Enable(bool start_detection) OVERRIDE;
     78   virtual bool StartDetectionIfIdle() OVERRIDE;
     79   virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
     80 
     81   // NetworkStateHandlerObserver implementation:
     82   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
     83 
     84   // PortalDetectorStrategy::Delegate implementation:
     85   virtual int NoResponseResultCount() OVERRIDE;
     86   virtual base::TimeTicks AttemptStartTime() OVERRIDE;
     87   virtual base::TimeTicks GetCurrentTimeTicks() OVERRIDE;
     88 
     89  private:
     90   friend class NetworkPortalDetectorImplTest;
     91   friend class NetworkPortalDetectorImplBrowserTest;
     92 
     93   struct DetectionAttemptCompletedReport {
     94     DetectionAttemptCompletedReport();
     95 
     96     DetectionAttemptCompletedReport(const std::string network_name,
     97                                     const std::string network_id,
     98                                     captive_portal::CaptivePortalResult result,
     99                                     int response_code);
    100 
    101     void Report() const;
    102 
    103     bool Equals(const DetectionAttemptCompletedReport& o) const;
    104 
    105     std::string network_name;
    106     std::string network_id;
    107     captive_portal::CaptivePortalResult result;
    108     int response_code;
    109   };
    110 
    111   typedef std::string NetworkId;
    112   typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
    113 
    114   enum State {
    115     // No portal check is running.
    116     STATE_IDLE = 0,
    117     // Waiting for portal check.
    118     STATE_PORTAL_CHECK_PENDING,
    119     // Portal check is in progress.
    120     STATE_CHECKING_FOR_PORTAL,
    121   };
    122 
    123   // Starts detection process.
    124   void StartDetection();
    125 
    126   // Stops whole detection process.
    127   void StopDetection();
    128 
    129   // Initiates Captive Portal detection attempt after |delay|.
    130   void ScheduleAttempt(const base::TimeDelta& delay);
    131 
    132   // Starts detection attempt.
    133   void StartAttempt();
    134 
    135   // Called when portal check is timed out. Cancels portal check and calls
    136   // OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as a result.
    137   void OnAttemptTimeout();
    138 
    139   // Called by CaptivePortalDetector when detection attempt completes.
    140   void OnAttemptCompleted(
    141       const captive_portal::CaptivePortalDetector::Results& results);
    142 
    143   // content::NotificationObserver implementation:
    144   virtual void Observe(int type,
    145                        const content::NotificationSource& source,
    146                        const content::NotificationDetails& details) OVERRIDE;
    147 
    148   // Stores captive portal state for a |network| and notifies observers.
    149   void OnDetectionCompleted(const NetworkState* network,
    150                             const CaptivePortalState& results);
    151 
    152   // Notifies observers that portal detection is completed for a |network|.
    153   void NotifyDetectionCompleted(const NetworkState* network,
    154                                 const CaptivePortalState& state);
    155 
    156   State state() const { return state_; }
    157 
    158   bool is_idle() const {
    159     return state_ == STATE_IDLE;
    160   }
    161   bool is_portal_check_pending() const {
    162     return state_ == STATE_PORTAL_CHECK_PENDING;
    163   }
    164   bool is_checking_for_portal() const {
    165     return state_ == STATE_CHECKING_FOR_PORTAL;
    166   }
    167 
    168   int same_detection_result_count_for_testing() const {
    169     return same_detection_result_count_;
    170   }
    171 
    172   int no_response_result_count_for_testing() const {
    173     return no_response_result_count_;
    174   }
    175 
    176   void set_no_response_result_count_for_testing(int count) {
    177     no_response_result_count_ = count;
    178   }
    179 
    180   // Returns delay before next portal check. Used by unit tests.
    181   const base::TimeDelta& next_attempt_delay_for_testing() const {
    182     return next_attempt_delay_;
    183   }
    184 
    185   // Returns true if attempt timeout callback isn't fired or
    186   // cancelled.
    187   bool AttemptTimeoutIsCancelledForTesting() const;
    188 
    189   // Record detection stats such as detection duration and detection
    190   // result in UMA.
    191   void RecordDetectionStats(const NetworkState* network,
    192                             CaptivePortalStatus status);
    193 
    194   // Resets strategy and all counters used in computations of
    195   // timeouts.
    196   void ResetStrategyAndCounters();
    197 
    198   // Sets current test time ticks. Used by unit tests.
    199   void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
    200     time_ticks_for_testing_ = time_ticks;
    201   }
    202 
    203   // Advances current test time ticks. Used by unit tests.
    204   void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
    205     time_ticks_for_testing_ += delta;
    206   }
    207 
    208   // Name of the default network.
    209   std::string default_network_name_;
    210 
    211   // Unique identifier of the default network.
    212   std::string default_network_id_;
    213 
    214   // Connection state of the default network.
    215   std::string default_connection_state_;
    216 
    217   State state_;
    218   CaptivePortalStateMap portal_state_map_;
    219   ObserverList<Observer> observers_;
    220 
    221   base::CancelableClosure attempt_task_;
    222   base::CancelableClosure attempt_timeout_;
    223 
    224   // URL that returns a 204 response code when connected to the Internet.
    225   GURL test_url_;
    226 
    227   // Detector for checking default network for a portal state.
    228   scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
    229 
    230   // True if the NetworkPortalDetector is enabled.
    231   bool enabled_;
    232 
    233   // Start time of portal detection.
    234   base::TimeTicks detection_start_time_;
    235 
    236   // Start time of detection attempt.
    237   base::TimeTicks attempt_start_time_;
    238 
    239   // Delay before next portal detection.
    240   base::TimeDelta next_attempt_delay_;
    241 
    242   // Current detection strategy.
    243   scoped_ptr<PortalDetectorStrategy> strategy_;
    244 
    245   // Last received result from captive portal detector.
    246   CaptivePortalStatus last_detection_result_;
    247 
    248   // Number of detection attempts with same result in a row.
    249   int same_detection_result_count_;
    250 
    251   // Number of detection attempts in a row with NO RESPONSE result.
    252   int no_response_result_count_;
    253 
    254   // UI notification controller about captive portal state.
    255   NetworkPortalNotificationController notification_controller_;
    256 
    257   content::NotificationRegistrar registrar_;
    258 
    259   // Test time ticks used by unit tests.
    260   base::TimeTicks time_ticks_for_testing_;
    261 
    262   // Contents of a last log message about completed detection attempt.
    263   DetectionAttemptCompletedReport attempt_completed_report_;
    264 
    265   base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_factory_;
    266 
    267   DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
    268 };
    269 
    270 }  // namespace chromeos
    271 
    272 #endif  // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
    273