network_portal_detector_impl.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/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.h"
20#include "chrome/browser/captive_portal/captive_portal_detector.h"
21#include "chrome/browser/chromeos/cros/network_library.h"
22#include "chrome/browser/chromeos/net/network_portal_detector.h"
23#include "content/public/browser/notification_observer.h"
24#include "content/public/browser/notification_registrar.h"
25#include "googleurl/src/gurl.h"
26#include "net/url_request/url_fetcher.h"
27
28namespace net {
29class URLRequestContextGetter;
30}
31
32namespace chromeos {
33
34// This class handles all notifications about network changes from
35// NetworkLibrary and delegates portal detection for the active
36// network to CaptivePortalService.
37class NetworkPortalDetectorImpl
38    : public NetworkPortalDetector,
39      public base::NonThreadSafe,
40      public chromeos::NetworkLibrary::NetworkManagerObserver,
41      public chromeos::NetworkLibrary::NetworkObserver,
42      public content::NotificationObserver {
43 public:
44  explicit NetworkPortalDetectorImpl(
45      const scoped_refptr<net::URLRequestContextGetter>& request_context);
46  virtual ~NetworkPortalDetectorImpl();
47
48  // NetworkPortalDetector implementation:
49  virtual void Init() OVERRIDE;
50  virtual void Shutdown() OVERRIDE;
51  virtual void AddObserver(Observer* observer) OVERRIDE;
52  virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
53  virtual void RemoveObserver(Observer* observer) OVERRIDE;
54  virtual CaptivePortalState GetCaptivePortalState(
55      const chromeos::Network* network) OVERRIDE;
56  virtual bool IsEnabled() OVERRIDE;
57  virtual void Enable(bool start_detection) OVERRIDE;
58  virtual void EnableLazyDetection() OVERRIDE;
59  virtual void DisableLazyDetection() OVERRIDE;
60
61  // NetworkLibrary::NetworkManagerObserver implementation:
62  virtual void OnNetworkManagerChanged(chromeos::NetworkLibrary* cros) OVERRIDE;
63
64  // NetworkLibrary::NetworkObserver implementation:
65  virtual void OnNetworkChanged(chromeos::NetworkLibrary* cros,
66                                const chromeos::Network* network) OVERRIDE;
67
68 private:
69  friend class NetworkPortalDetectorImplTest;
70
71  typedef std::string NetworkId;
72  typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
73  enum State {
74    // No portal check is running.
75    STATE_IDLE = 0,
76    // Waiting for portal check.
77    STATE_PORTAL_CHECK_PENDING,
78    // Portal check is in progress.
79    STATE_CHECKING_FOR_PORTAL,
80  };
81
82  // Initiates Captive Portal detection after |delay|.
83  void DetectCaptivePortal(const base::TimeDelta& delay);
84
85  void DetectCaptivePortalTask();
86
87  // Called when portal check is timed out. Cancels portal check and
88  // calls OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as
89  // a result.
90  void PortalDetectionTimeout();
91
92  void CancelPortalDetection();
93
94  // Called by CaptivePortalDetector when detection completes.
95  void OnPortalDetectionCompleted(
96      const captive_portal::CaptivePortalDetector::Results& results);
97
98  // Tries to perform portal detection in "lazy" mode. Does nothing in
99  // the case of already pending/processing detection request.
100  void TryLazyDetection();
101
102  // content::NotificationObserver implementation:
103  virtual void Observe(int type,
104                       const content::NotificationSource& source,
105                       const content::NotificationDetails& details) OVERRIDE;
106
107  // Returns true if we're waiting for portal check.
108  bool IsPortalCheckPending() const;
109
110  // Returns true if portal check is in progress.
111  bool IsCheckingForPortal() const;
112
113  // Stores captive portal state for a |network|.
114  void SetCaptivePortalState(const Network* network,
115                             const CaptivePortalState& results);
116
117  // Notifies observers that portal detection is completed for a |network|.
118  void NotifyPortalDetectionCompleted(const Network* network,
119                                      const CaptivePortalState& state);
120
121  // Returns the current TimeTicks.
122  base::TimeTicks GetCurrentTimeTicks() const;
123
124  State state() { return state_; }
125
126  // Returns current number of portal detection attempts.
127  // Used by unit tests.
128  int attempt_count_for_testing() { return attempt_count_; }
129
130  // Sets minimum time between consecutive portal checks for the same
131  // network. Used by unit tests.
132  void set_min_time_between_attempts_for_testing(const base::TimeDelta& delta) {
133    min_time_between_attempts_ = delta;
134  }
135
136  // Sets default interval between consecutive portal checks for a
137  // network in portal state. Used by unit tests.
138  void set_lazy_check_interval_for_testing(const base::TimeDelta& delta) {
139    lazy_check_interval_ = delta;
140  }
141
142  // Sets portal detection timeout. Used by unit tests.
143  void set_request_timeout_for_testing(const base::TimeDelta& timeout) {
144    request_timeout_ = timeout;
145  }
146
147  // Returns delay before next portal check. Used by unit tests.
148  const base::TimeDelta& next_attempt_delay_for_testing() {
149    return next_attempt_delay_;
150  }
151
152  // Sets current test time ticks. Used by unit tests.
153  void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
154    time_ticks_for_testing_ = time_ticks;
155  }
156
157  // Advances current test time ticks. Used by unit tests.
158  void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
159    time_ticks_for_testing_ += delta;
160  }
161
162  // Returns true if detection timeout callback isn't fired or
163  // cancelled.
164  bool DetectionTimeoutIsCancelledForTesting() const;
165
166  // Unique identifier of the active network.
167  std::string active_network_id_;
168
169  // Service path of the active network.
170  std::string active_service_path_;
171
172  // Connection state of the active network.
173  ConnectionState active_connection_state_;
174
175  State state_;
176  CaptivePortalStateMap portal_state_map_;
177  ObserverList<Observer> observers_;
178
179  base::CancelableClosure detection_task_;
180  base::CancelableClosure detection_timeout_;
181
182  // URL that returns a 204 response code when connected to the Internet.
183  GURL test_url_;
184
185  // Detector for checking active network for a portal state.
186  scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
187
188  // True if the NetworkPortalDetector is enabled.
189  bool enabled_;
190
191  base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_ptr_factory_;
192
193  // Number of portal detection attemps for an active network.
194  int attempt_count_;
195
196  // True if lazy detection is enabled.
197  bool lazy_detection_enabled_;
198
199  // Time between consecutive portal checks for a network in lazy
200  // mode.
201  base::TimeDelta lazy_check_interval_;
202
203  // Minimum time between consecutive portal checks for the same
204  // active network.
205  base::TimeDelta min_time_between_attempts_;
206
207  // Start time of portal detection.
208  base::TimeTicks detection_start_time_;
209
210  // Start time of portal detection attempt.
211  base::TimeTicks attempt_start_time_;
212
213  // Timeout for a portal detection.
214  base::TimeDelta request_timeout_;
215
216  // Delay before next portal detection.
217  base::TimeDelta next_attempt_delay_;
218
219  // Test time ticks used by unit tests.
220  base::TimeTicks time_ticks_for_testing_;
221
222  content::NotificationRegistrar registrar_;
223
224  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
225};
226
227}  // namespace chromeos
228
229#endif  // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
230