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 static const char kDetectionResultHistogram
[];
46 static const char kDetectionDurationHistogram
[];
47 static const char kShillOnlineHistogram
[];
48 static const char kShillPortalHistogram
[];
49 static const char kShillOfflineHistogram
[];
51 explicit NetworkPortalDetectorImpl(
52 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
);
53 virtual ~NetworkPortalDetectorImpl();
55 // NetworkPortalDetector implementation:
56 virtual void AddObserver(Observer
* observer
) OVERRIDE
;
57 virtual void AddAndFireObserver(Observer
* observer
) OVERRIDE
;
58 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
;
59 virtual CaptivePortalState
GetCaptivePortalState(
60 const chromeos::NetworkState
* network
) OVERRIDE
;
61 virtual bool IsEnabled() OVERRIDE
;
62 virtual void Enable(bool start_detection
) OVERRIDE
;
63 virtual bool StartDetectionIfIdle() OVERRIDE
;
64 virtual void EnableLazyDetection() OVERRIDE
;
65 virtual void DisableLazyDetection() OVERRIDE
;
67 // NetworkStateHandlerObserver implementation:
68 virtual void DefaultNetworkChanged(const NetworkState
* network
) OVERRIDE
;
71 friend class NetworkPortalDetectorImplTest
;
73 typedef std::string NetworkId
;
74 typedef base::hash_map
<NetworkId
, CaptivePortalState
> CaptivePortalStateMap
;
77 // No portal check is running.
79 // Waiting for portal check.
80 STATE_PORTAL_CHECK_PENDING
,
81 // Portal check is in progress.
82 STATE_CHECKING_FOR_PORTAL
,
85 // Basic unit used in detection timeout computation.
86 static const int kBaseRequestTimeoutSec
= 5;
88 // Single detection attempt timeout in lazy mode.
89 static const int kLazyRequestTimeoutSec
= 15;
91 // Internal predicate which describes set of states from which
92 // DetectCaptivePortal() can be called.
93 bool CanPerformDetection() const;
95 // Initiates Captive Portal detection after |delay|.
96 // CanPerformDetection() *must* be kept before call to this method.
97 void DetectCaptivePortal(const base::TimeDelta
& delay
);
99 void DetectCaptivePortalTask();
101 // Called when portal check is timed out. Cancels portal check and
102 // calls OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as
104 void PortalDetectionTimeout();
106 void CancelPortalDetection();
108 // Called by CaptivePortalDetector when detection completes.
109 void OnPortalDetectionCompleted(
110 const captive_portal::CaptivePortalDetector::Results
& results
);
112 // Tries to perform portal detection in "lazy" mode. Does nothing in
113 // the case of already pending/processing detection request.
114 void TryLazyDetection();
116 // content::NotificationObserver implementation:
117 virtual void Observe(int type
,
118 const content::NotificationSource
& source
,
119 const content::NotificationDetails
& details
) OVERRIDE
;
121 // Returns true if we're waiting for portal check.
122 bool IsPortalCheckPending() const;
124 // Returns true if portal check is in progress.
125 bool IsCheckingForPortal() const;
127 // Stores captive portal state for a |network|.
128 void SetCaptivePortalState(const NetworkState
* network
,
129 const CaptivePortalState
& results
);
131 // Notifies observers that portal detection is completed for a |network|.
132 void NotifyPortalDetectionCompleted(const NetworkState
* network
,
133 const CaptivePortalState
& state
);
135 // Returns the current TimeTicks.
136 base::TimeTicks
GetCurrentTimeTicks() const;
138 State
state() const { return state_
; }
140 bool lazy_detection_enabled() const { return lazy_detection_enabled_
; }
142 // Returns current number of portal detection attempts.
143 // Used by unit tests.
144 int attempt_count_for_testing() const { return attempt_count_
; }
146 // Sets current number of detection attempts.
147 // Used by unit tests.
148 void set_attempt_count_for_testing(int attempt_count
) {
149 attempt_count_
= attempt_count
;
152 // Sets minimum time between consecutive portal checks for the same
153 // network. Used by unit tests.
154 void set_min_time_between_attempts_for_testing(const base::TimeDelta
& delta
) {
155 min_time_between_attempts_
= delta
;
158 // Sets default interval between consecutive portal checks for a
159 // network in portal state. Used by unit tests.
160 void set_lazy_check_interval_for_testing(const base::TimeDelta
& delta
) {
161 lazy_check_interval_
= delta
;
164 // Sets portal detection timeout. Used by unit tests.
165 void set_request_timeout_for_testing(const base::TimeDelta
& timeout
) {
166 request_timeout_for_testing_
= timeout
;
167 request_timeout_for_testing_initialized_
= true;
170 // Returns delay before next portal check. Used by unit tests.
171 const base::TimeDelta
& next_attempt_delay_for_testing() const {
172 return next_attempt_delay_
;
175 // Sets current test time ticks. Used by unit tests.
176 void set_time_ticks_for_testing(const base::TimeTicks
& time_ticks
) {
177 time_ticks_for_testing_
= time_ticks
;
180 // Advances current test time ticks. Used by unit tests.
181 void advance_time_ticks_for_testing(const base::TimeDelta
& delta
) {
182 time_ticks_for_testing_
+= delta
;
185 // Returns true if detection timeout callback isn't fired or
187 bool DetectionTimeoutIsCancelledForTesting() const;
189 // Returns timeout for current (or immediate) detection attempt.
190 // The following rules are used for timeout computation:
191 // * if default (active) network is NULL, kBaseRequestTimeoutSec is used
192 // * if lazy detection mode is enabled, kLazyRequestTimeoutSec is used
193 // * otherwise, timeout equals to |attempt_count_| * kBaseRequestTimeoutSec
194 int GetRequestTimeoutSec() const;
196 // Record detection stats such as detection duration and detection
198 void RecordDetectionStats(const NetworkState
* network
,
199 CaptivePortalStatus status
);
201 // Name of the default network.
202 std::string default_network_name_
;
204 // Unique identifier of the default network.
205 std::string default_network_id_
;
207 // Service path of the default network.
208 std::string default_service_path_
;
210 // Connection state of the default network.
211 std::string default_connection_state_
;
214 CaptivePortalStateMap portal_state_map_
;
215 ObserverList
<Observer
> observers_
;
217 base::CancelableClosure detection_task_
;
218 base::CancelableClosure detection_timeout_
;
220 // URL that returns a 204 response code when connected to the Internet.
223 // Detector for checking default network for a portal state.
224 scoped_ptr
<captive_portal::CaptivePortalDetector
> captive_portal_detector_
;
226 // True if the NetworkPortalDetector is enabled.
229 base::WeakPtrFactory
<NetworkPortalDetectorImpl
> weak_ptr_factory_
;
231 // Number of portal detection attemps for a default network.
234 bool lazy_detection_enabled_
;
236 // Time between consecutive portal checks for a network in lazy
238 base::TimeDelta lazy_check_interval_
;
240 // Minimum time between consecutive portal checks for the same
242 base::TimeDelta min_time_between_attempts_
;
244 // Start time of portal detection.
245 base::TimeTicks detection_start_time_
;
247 // Start time of portal detection attempt.
248 base::TimeTicks attempt_start_time_
;
250 // Delay before next portal detection.
251 base::TimeDelta next_attempt_delay_
;
253 // Test time ticks used by unit tests.
254 base::TimeTicks time_ticks_for_testing_
;
256 // Test timeout for a portal detection used by unit tests.
257 base::TimeDelta request_timeout_for_testing_
;
259 // True if |request_timeout_for_testing_| is initialized.
260 bool request_timeout_for_testing_initialized_
;
262 content::NotificationRegistrar registrar_
;
264 DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl
);
267 } // namespace chromeos
269 #endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_