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.
5 #ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
6 #define CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
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"
29 class URLRequestContextGetter;
36 // This class handles all notifications about network changes from
37 // NetworkStateHandler 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 {
45 explicit NetworkPortalDetectorImpl(
46 const scoped_refptr<net::URLRequestContextGetter>& request_context);
47 virtual ~NetworkPortalDetectorImpl();
49 // NetworkPortalDetector implementation:
50 virtual void AddObserver(Observer* observer) OVERRIDE;
51 virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
52 virtual void RemoveObserver(Observer* observer) OVERRIDE;
53 virtual CaptivePortalState GetCaptivePortalState(
54 const chromeos::NetworkState* network) OVERRIDE;
55 virtual bool IsEnabled() OVERRIDE;
56 virtual void Enable(bool start_detection) OVERRIDE;
57 virtual bool StartDetectionIfIdle() OVERRIDE;
58 virtual void EnableLazyDetection() OVERRIDE;
59 virtual void DisableLazyDetection() OVERRIDE;
61 // NetworkStateHandlerObserver implementation:
62 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
65 friend class NetworkPortalDetectorImplTest;
67 typedef std::string NetworkId;
68 typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
71 // No portal check is running.
73 // Waiting for portal check.
74 STATE_PORTAL_CHECK_PENDING,
75 // Portal check is in progress.
76 STATE_CHECKING_FOR_PORTAL,
79 // Basic unit used in detection timeout computation.
80 static const int kBaseRequestTimeoutSec = 5;
82 // Single detection attempt timeout in lazy mode.
83 static const int kLazyRequestTimeoutSec = 15;
85 // Internal predicate which describes set of states from which
86 // DetectCaptivePortal() can be called.
87 bool CanPerformDetection() const;
89 // Initiates Captive Portal detection after |delay|.
90 // CanPerformDetection() *must* be kept before call to this method.
91 void DetectCaptivePortal(const base::TimeDelta& delay);
93 void DetectCaptivePortalTask();
95 // Called when portal check is timed out. Cancels portal check and
96 // calls OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as
98 void PortalDetectionTimeout();
100 void CancelPortalDetection();
102 // Called by CaptivePortalDetector when detection completes.
103 void OnPortalDetectionCompleted(
104 const captive_portal::CaptivePortalDetector::Results& results);
106 // Tries to perform portal detection in "lazy" mode. Does nothing in
107 // the case of already pending/processing detection request.
108 void TryLazyDetection();
110 // content::NotificationObserver implementation:
111 virtual void Observe(int type,
112 const content::NotificationSource& source,
113 const content::NotificationDetails& details) OVERRIDE;
115 // Returns true if we're waiting for portal check.
116 bool IsPortalCheckPending() const;
118 // Returns true if portal check is in progress.
119 bool IsCheckingForPortal() const;
121 // Stores captive portal state for a |network|.
122 void SetCaptivePortalState(const NetworkState* network,
123 const CaptivePortalState& results);
125 // Notifies observers that portal detection is completed for a |network|.
126 void NotifyPortalDetectionCompleted(const NetworkState* network,
127 const CaptivePortalState& state);
129 // Returns the current TimeTicks.
130 base::TimeTicks GetCurrentTimeTicks() const;
132 State state() const { return state_; }
134 bool lazy_detection_enabled() const { return lazy_detection_enabled_; }
136 // Returns current number of portal detection attempts.
137 // Used by unit tests.
138 int attempt_count_for_testing() const { return attempt_count_; }
140 // Sets current number of detection attempts.
141 // Used by unit tests.
142 void set_attempt_count_for_testing(int attempt_count) {
143 attempt_count_ = attempt_count;
146 // Sets minimum time between consecutive portal checks for the same
147 // network. Used by unit tests.
148 void set_min_time_between_attempts_for_testing(const base::TimeDelta& delta) {
149 min_time_between_attempts_ = delta;
152 // Sets default interval between consecutive portal checks for a
153 // network in portal state. Used by unit tests.
154 void set_lazy_check_interval_for_testing(const base::TimeDelta& delta) {
155 lazy_check_interval_ = delta;
158 // Sets portal detection timeout. Used by unit tests.
159 void set_request_timeout_for_testing(const base::TimeDelta& timeout) {
160 request_timeout_for_testing_ = timeout;
161 request_timeout_for_testing_initialized_ = true;
164 // Returns delay before next portal check. Used by unit tests.
165 const base::TimeDelta& next_attempt_delay_for_testing() const {
166 return next_attempt_delay_;
169 // Sets current test time ticks. Used by unit tests.
170 void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
171 time_ticks_for_testing_ = time_ticks;
174 // Advances current test time ticks. Used by unit tests.
175 void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
176 time_ticks_for_testing_ += delta;
179 // Returns true if detection timeout callback isn't fired or
181 bool DetectionTimeoutIsCancelledForTesting() const;
183 // Returns timeout for current (or immediate) detection attempt.
184 // The following rules are used for timeout computation:
185 // * if default (active) network is NULL, kBaseRequestTimeoutSec is used
186 // * if lazy detection mode is enabled, kLazyRequestTimeoutSec is used
187 // * otherwise, timeout equals to |attempt_count_| * kBaseRequestTimeoutSec
188 int GetRequestTimeoutSec() const;
190 // Unique identifier of the default network.
191 std::string default_network_id_;
193 // Service path of the default network.
194 std::string default_service_path_;
196 // Connection state of the default network.
197 std::string default_connection_state_;
200 CaptivePortalStateMap portal_state_map_;
201 ObserverList<Observer> observers_;
203 base::CancelableClosure detection_task_;
204 base::CancelableClosure detection_timeout_;
206 // URL that returns a 204 response code when connected to the Internet.
209 // Detector for checking default network for a portal state.
210 scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
212 // True if the NetworkPortalDetector is enabled.
215 base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_ptr_factory_;
217 // Number of portal detection attemps for a default network.
220 bool lazy_detection_enabled_;
222 // Time between consecutive portal checks for a network in lazy
224 base::TimeDelta lazy_check_interval_;
226 // Minimum time between consecutive portal checks for the same
228 base::TimeDelta min_time_between_attempts_;
230 // Start time of portal detection.
231 base::TimeTicks detection_start_time_;
233 // Start time of portal detection attempt.
234 base::TimeTicks attempt_start_time_;
236 // Delay before next portal detection.
237 base::TimeDelta next_attempt_delay_;
239 // Test time ticks used by unit tests.
240 base::TimeTicks time_ticks_for_testing_;
242 // Test timeout for a portal detection used by unit tests.
243 base::TimeDelta request_timeout_for_testing_;
245 // True if |request_timeout_for_testing_| is initialized.
246 bool request_timeout_for_testing_initialized_;
248 content::NotificationRegistrar registrar_;
250 DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
253 } // namespace chromeos
255 #endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_