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_detector.h" 21 #include "chrome/browser/chromeos/net/network_portal_detector_strategy.h" 22 #include "chrome/browser/chromeos/net/network_portal_notification_controller.h" 23 #include "chromeos/network/network_state_handler_observer.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 explicit NetworkPortalDetectorImpl( 64 const scoped_refptr<net::URLRequestContextGetter>& request_context); 65 virtual ~NetworkPortalDetectorImpl(); 66 67 // NetworkPortalDetector implementation: 68 virtual void AddObserver(Observer* observer) OVERRIDE; 69 virtual void AddAndFireObserver(Observer* observer) OVERRIDE; 70 virtual void RemoveObserver(Observer* observer) OVERRIDE; 71 virtual CaptivePortalState GetCaptivePortalState( 72 const std::string& service_path) OVERRIDE; 73 virtual bool IsEnabled() OVERRIDE; 74 virtual void Enable(bool start_detection) OVERRIDE; 75 virtual bool StartDetectionIfIdle() OVERRIDE; 76 virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE; 77 78 // NetworkStateHandlerObserver implementation: 79 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE; 80 81 // PortalDetectorStrategy::Delegate implementation: 82 virtual int AttemptCount() OVERRIDE; 83 virtual base::TimeTicks AttemptStartTime() OVERRIDE; 84 virtual base::TimeTicks GetCurrentTimeTicks() OVERRIDE; 85 86 private: 87 friend class NetworkPortalDetectorImplTest; 88 friend class NetworkPortalDetectorImplBrowserTest; 89 90 typedef std::string NetworkId; 91 typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap; 92 93 enum State { 94 // No portal check is running. 95 STATE_IDLE = 0, 96 // Waiting for portal check. 97 STATE_PORTAL_CHECK_PENDING, 98 // Portal check is in progress. 99 STATE_CHECKING_FOR_PORTAL, 100 }; 101 102 // Starts detection process. 103 void StartDetection(); 104 105 // Stops whole detection process. 106 void StopDetection(); 107 108 // Internal predicate which describes set of states from which 109 // DetectCaptivePortal() can be called. 110 bool CanPerformAttempt() const; 111 112 // Initiates Captive Portal detection attempt after |delay|. 113 // You should check CanPerformAttempt() before calling this method. 114 void ScheduleAttempt(const base::TimeDelta& delay); 115 116 // Starts detection attempt. 117 void StartAttempt(); 118 119 // Called when portal check is timed out. Cancels portal check and calls 120 // OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as a result. 121 void OnAttemptTimeout(); 122 123 // Called by CaptivePortalDetector when detection attempt completes. 124 void OnAttemptCompleted( 125 const captive_portal::CaptivePortalDetector::Results& results); 126 127 // content::NotificationObserver implementation: 128 virtual void Observe(int type, 129 const content::NotificationSource& source, 130 const content::NotificationDetails& details) OVERRIDE; 131 132 // Stores captive portal state for a |network| and notifies observers. 133 void OnDetectionCompleted(const NetworkState* network, 134 const CaptivePortalState& results); 135 136 // Notifies observers that portal detection is completed for a |network|. 137 void NotifyDetectionCompleted(const NetworkState* network, 138 const CaptivePortalState& state); 139 140 State state() const { return state_; } 141 142 bool is_idle() const { 143 return state_ == STATE_IDLE; 144 } 145 bool is_portal_check_pending() const { 146 return state_ == STATE_PORTAL_CHECK_PENDING; 147 } 148 bool is_checking_for_portal() const { 149 return state_ == STATE_CHECKING_FOR_PORTAL; 150 } 151 152 int attempt_count_for_testing() { 153 return attempt_count_; 154 } 155 156 void set_attempt_count_for_testing(int attempt_count) { 157 attempt_count_ = attempt_count; 158 } 159 160 // Returns delay before next portal check. Used by unit tests. 161 const base::TimeDelta& next_attempt_delay_for_testing() const { 162 return next_attempt_delay_; 163 } 164 165 // Returns true if attempt timeout callback isn't fired or 166 // cancelled. 167 bool AttemptTimeoutIsCancelledForTesting() const; 168 169 // Record detection stats such as detection duration and detection 170 // result in UMA. 171 void RecordDetectionStats(const NetworkState* network, 172 CaptivePortalStatus status); 173 174 // Sets current test time ticks. Used by unit tests. 175 void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) { 176 time_ticks_for_testing_ = time_ticks; 177 } 178 179 // Advances current test time ticks. Used by unit tests. 180 void advance_time_ticks_for_testing(const base::TimeDelta& delta) { 181 time_ticks_for_testing_ += delta; 182 } 183 184 // Name of the default network. 185 std::string default_network_name_; 186 187 // Unique identifier of the default network. 188 std::string default_network_id_; 189 190 // Service path of the default network. 191 std::string default_service_path_; 192 193 // Connection state of the default network. 194 std::string default_connection_state_; 195 196 State state_; 197 CaptivePortalStateMap portal_state_map_; 198 ObserverList<Observer> observers_; 199 200 base::CancelableClosure attempt_task_; 201 base::CancelableClosure attempt_timeout_; 202 203 // URL that returns a 204 response code when connected to the Internet. 204 GURL test_url_; 205 206 // Detector for checking default network for a portal state. 207 scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_; 208 209 // True if the NetworkPortalDetector is enabled. 210 bool enabled_; 211 212 base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_factory_; 213 214 // Start time of portal detection. 215 base::TimeTicks detection_start_time_; 216 217 // Start time of detection attempt. 218 base::TimeTicks attempt_start_time_; 219 220 // Number of already performed detection attempts. 221 int attempt_count_; 222 223 // Delay before next portal detection. 224 base::TimeDelta next_attempt_delay_; 225 226 // Current detection strategy. 227 scoped_ptr<PortalDetectorStrategy> strategy_; 228 229 // UI notification controller about captive portal state. 230 NetworkPortalNotificationController notification_controller_; 231 232 content::NotificationRegistrar registrar_; 233 234 // Test time ticks used by unit tests. 235 base::TimeTicks time_ticks_for_testing_; 236 237 DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl); 238 }; 239 240 } // namespace chromeos 241 242 #endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_ 243