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 <map> 9 #include <memory> 10 #include <string> 11 12 #include "base/callback_forward.h" 13 #include "base/cancelable_callback.h" 14 #include "base/compiler_specific.h" 15 #include "base/macros.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/scoped_refptr.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/observer_list.h" 20 #include "base/sequence_checker.h" 21 #include "base/time/time.h" 22 #include "chromeos/network/network_state_handler_observer.h" 23 #include "chromeos/network/portal_detector/network_portal_detector.h" 24 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h" 25 #include "components/captive_portal/core/captive_portal_detector.h" 26 #include "components/captive_portal/core/captive_portal_types.h" 27 #include "content/public/browser/notification_observer.h" 28 #include "content/public/browser/notification_registrar.h" 29 #include "url/gurl.h" 30 31 namespace base { 32 class Value; 33 } 34 35 namespace network { 36 class SharedURLLoaderFactory; 37 namespace mojom { 38 class URLLoaderFactory; 39 } 40 } // namespace network 41 42 namespace chromeos { 43 44 class NetworkState; 45 46 // This class handles all notifications about network changes from 47 // NetworkStateHandler and delegates portal detection for the default 48 // network to captive_portal::CaptivePortalService. 49 class NetworkPortalDetectorImpl : public NetworkPortalDetector, 50 public chromeos::NetworkStateHandlerObserver, 51 public content::NotificationObserver, 52 public PortalDetectorStrategy::Delegate { 53 public: 54 explicit NetworkPortalDetectorImpl( 55 network::mojom::URLLoaderFactory* loader_factory_for_testing = nullptr); 56 ~NetworkPortalDetectorImpl() override; 57 58 private: 59 friend class NetworkPortalDetectorImplTest; 60 friend class NetworkPortalDetectorImplBrowserTest; 61 62 enum State { 63 // No portal check is running. 64 STATE_IDLE = 0, 65 // Waiting for portal check. 66 STATE_PORTAL_CHECK_PENDING, 67 // Portal check is in progress. 68 STATE_CHECKING_FOR_PORTAL, 69 }; 70 71 // Starts detection process. 72 void StartDetection(); 73 74 // Stops whole detection process. 75 void StopDetection(); 76 77 // Stops and restarts the detection process. 78 void RetryDetection(); 79 80 // Initiates Captive Portal detection attempt after |delay|. 81 void ScheduleAttempt(const base::TimeDelta& delay); 82 83 // Starts detection attempt. 84 void StartAttempt(); 85 86 // Called when portal check is timed out. Cancels portal check and calls 87 // OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as a result. 88 void OnAttemptTimeout(); 89 90 // Called by CaptivePortalDetector when detection attempt completes. 91 void OnAttemptCompleted( 92 const captive_portal::CaptivePortalDetector::Results& results); 93 94 // NetworkPortalDetector implementation: 95 void AddObserver(Observer* observer) override; 96 void AddAndFireObserver(Observer* observer) override; 97 void RemoveObserver(Observer* observer) override; 98 CaptivePortalStatus GetCaptivePortalStatus() override; 99 bool IsEnabled() override; 100 void Enable(bool start_detection) override; 101 void StartPortalDetection() override; 102 void SetStrategy(PortalDetectorStrategy::StrategyId id) override; 103 104 // NetworkStateHandlerObserver implementation: 105 void DefaultNetworkChanged(const NetworkState* network) override; 106 107 // PortalDetectorStrategy::Delegate implementation: 108 int NoResponseResultCount() override; 109 base::TimeTicks AttemptStartTime() override; 110 base::TimeTicks NowTicks() const override; 111 112 // content::NotificationObserver implementation: 113 void Observe(int type, 114 const content::NotificationSource& source, 115 const content::NotificationDetails& details) override; 116 117 // Called synchronously from OnAttemptCompleted with the current default 118 // network. Stores the captive portal status and notifies observers. 119 void DetectionCompleted(const NetworkState* network, 120 const CaptivePortalStatus& results, 121 int response_code); 122 state()123 State state() const { return state_; } 124 is_idle()125 bool is_idle() const { return state_ == STATE_IDLE; } is_portal_check_pending()126 bool is_portal_check_pending() const { 127 return state_ == STATE_PORTAL_CHECK_PENDING; 128 } is_checking_for_portal()129 bool is_checking_for_portal() const { 130 return state_ == STATE_CHECKING_FOR_PORTAL; 131 } 132 same_detection_result_count_for_testing()133 int same_detection_result_count_for_testing() const { 134 return same_detection_result_count_; 135 } 136 no_response_result_count_for_testing()137 int no_response_result_count_for_testing() const { 138 return no_response_result_count_; 139 } 140 set_no_response_result_count_for_testing(int count)141 void set_no_response_result_count_for_testing(int count) { 142 no_response_result_count_ = count; 143 } 144 145 // Returns delay before next portal check. Used by unit tests. next_attempt_delay_for_testing()146 const base::TimeDelta& next_attempt_delay_for_testing() const { 147 return next_attempt_delay_; 148 } 149 150 // Returns true if attempt timeout callback isn't fired or 151 // cancelled. 152 bool AttemptTimeoutIsCancelledForTesting() const; 153 154 // Resets strategy and all counters used in computations of 155 // timeouts. 156 void ResetStrategyAndCounters(); 157 158 // Sets current test time ticks. Used by unit tests. set_time_ticks_for_testing(const base::TimeTicks & time_ticks)159 void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) { 160 time_ticks_for_testing_ = time_ticks; 161 } 162 163 // Advances current test time ticks. Used by unit tests. advance_time_ticks_for_testing(const base::TimeDelta & delta)164 void advance_time_ticks_for_testing(const base::TimeDelta& delta) { 165 time_ticks_for_testing_ += delta; 166 } 167 default_network_id_for_testing()168 const std::string& default_network_id_for_testing() const { 169 return default_network_id_; 170 } response_code_for_testing()171 int response_code_for_testing() const { return response_code_for_testing_; } 172 173 // Unique identifier of the default network. 174 std::string default_network_id_; 175 176 // Connection state of the default network. 177 std::string default_connection_state_; 178 179 // Proxy configuration of the default network. 180 base::Value default_proxy_config_; 181 182 CaptivePortalStatus default_portal_status_ = CAPTIVE_PORTAL_STATUS_UNKNOWN; 183 int response_code_for_testing_ = -1; 184 185 State state_ = STATE_IDLE; 186 base::ObserverList<Observer>::Unchecked observers_; 187 188 base::CancelableClosure attempt_task_; 189 base::CancelableClosure attempt_timeout_; 190 191 // Reference to a SharedURLLoaderFactory used to detect portals. 192 scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; 193 194 // Detector for checking default network for a portal state. 195 std::unique_ptr<captive_portal::CaptivePortalDetector> 196 captive_portal_detector_; 197 198 // True if the NetworkPortalDetector is enabled. 199 bool enabled_ = false; 200 201 // Start time of portal detection. 202 base::TimeTicks detection_start_time_; 203 204 // Start time of detection attempt. 205 base::TimeTicks attempt_start_time_; 206 207 // Delay before next portal detection. 208 base::TimeDelta next_attempt_delay_; 209 210 // Current detection strategy. 211 std::unique_ptr<PortalDetectorStrategy> strategy_; 212 213 // Last received result from captive portal detector. 214 CaptivePortalStatus last_detection_result_ = CAPTIVE_PORTAL_STATUS_UNKNOWN; 215 216 // Number of detection attempts with same result in a row. 217 int same_detection_result_count_ = 0; 218 219 // Number of detection attempts in a row with NO RESPONSE result. 220 int no_response_result_count_ = 0; 221 222 SEQUENCE_CHECKER(sequence_checker_); 223 224 content::NotificationRegistrar registrar_; 225 226 // Test time ticks used by unit tests. 227 base::TimeTicks time_ticks_for_testing_; 228 229 base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_factory_{this}; 230 231 DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl); 232 }; 233 234 } // namespace chromeos 235 236 #endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_ 237