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