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 31namespace net { 32class URLRequestContextGetter; 33} 34 35namespace chromeos { 36 37class 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. 42class 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