network_portal_detector_impl.h revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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/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"
26#include "url/gurl.h"
27
28namespace net {
29class URLRequestContextGetter;
30}
31
32namespace chromeos {
33
34class NetworkState;
35
36// This class handles all notifications about network changes from
37// NetworkLibrary and delegates portal detection for the default
38// network to CaptivePortalService.
39class NetworkPortalDetectorImpl
40    : public NetworkPortalDetector,
41      public base::NonThreadSafe,
42      public chromeos::NetworkStateHandlerObserver,
43      public content::NotificationObserver {
44 public:
45  explicit NetworkPortalDetectorImpl(
46      const scoped_refptr<net::URLRequestContextGetter>& request_context);
47  virtual ~NetworkPortalDetectorImpl();
48
49  // NetworkPortalDetector implementation:
50  virtual void Init() OVERRIDE;
51  virtual void Shutdown() OVERRIDE;
52  virtual void AddObserver(Observer* observer) OVERRIDE;
53  virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
54  virtual void RemoveObserver(Observer* observer) OVERRIDE;
55  virtual CaptivePortalState GetCaptivePortalState(
56      const chromeos::NetworkState* network) OVERRIDE;
57  virtual bool IsEnabled() OVERRIDE;
58  virtual void Enable(bool start_detection) OVERRIDE;
59  virtual bool StartDetectionIfIdle() OVERRIDE;
60  virtual void EnableLazyDetection() OVERRIDE;
61  virtual void DisableLazyDetection() OVERRIDE;
62
63  // NetworkStateHandlerObserver implementation:
64  virtual void NetworkManagerChanged() OVERRIDE;
65  virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
66
67 private:
68  friend class NetworkPortalDetectorImplTest;
69
70  typedef std::string NetworkId;
71  typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
72
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  // Basic unit used in detection timeout computation.
83  static const int kBaseRequestTimeoutSec = 5;
84
85  // Single detection attempt timeout in lazy mode.
86  static const int kLazyRequestTimeoutSec = 15;
87
88  // Internal predicate which describes set of states from which
89  // DetectCaptivePortal() can be called.
90  bool CanPerformDetection() const;
91
92  // Initiates Captive Portal detection after |delay|.
93  // CanPerformDetection() *must* be kept before call to this method.
94  void DetectCaptivePortal(const base::TimeDelta& delay);
95
96  void DetectCaptivePortalTask();
97
98  // Called when portal check is timed out. Cancels portal check and
99  // calls OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as
100  // a result.
101  void PortalDetectionTimeout();
102
103  void CancelPortalDetection();
104
105  // Called by CaptivePortalDetector when detection completes.
106  void OnPortalDetectionCompleted(
107      const captive_portal::CaptivePortalDetector::Results& results);
108
109  // Tries to perform portal detection in "lazy" mode. Does nothing in
110  // the case of already pending/processing detection request.
111  void TryLazyDetection();
112
113  // content::NotificationObserver implementation:
114  virtual void Observe(int type,
115                       const content::NotificationSource& source,
116                       const content::NotificationDetails& details) OVERRIDE;
117
118  // Returns true if we're waiting for portal check.
119  bool IsPortalCheckPending() const;
120
121  // Returns true if portal check is in progress.
122  bool IsCheckingForPortal() const;
123
124  // Stores captive portal state for a |network|.
125  void SetCaptivePortalState(const NetworkState* network,
126                             const CaptivePortalState& results);
127
128  // Notifies observers that portal detection is completed for a |network|.
129  void NotifyPortalDetectionCompleted(const NetworkState* network,
130                                      const CaptivePortalState& state);
131
132  // Returns the current TimeTicks.
133  base::TimeTicks GetCurrentTimeTicks() const;
134
135  State state() const { return state_; }
136
137  bool lazy_detection_enabled() const { return lazy_detection_enabled_; }
138
139  // Returns current number of portal detection attempts.
140  // Used by unit tests.
141  int attempt_count_for_testing() const { return attempt_count_; }
142
143  // Sets current number of detection attempts.
144  // Used by unit tests.
145  void set_attempt_count_for_testing(int attempt_count) {
146    attempt_count_ = attempt_count;
147  }
148
149  // Sets minimum time between consecutive portal checks for the same
150  // network. Used by unit tests.
151  void set_min_time_between_attempts_for_testing(const base::TimeDelta& delta) {
152    min_time_between_attempts_ = delta;
153  }
154
155  // Sets default interval between consecutive portal checks for a
156  // network in portal state. Used by unit tests.
157  void set_lazy_check_interval_for_testing(const base::TimeDelta& delta) {
158    lazy_check_interval_ = delta;
159  }
160
161  // Sets portal detection timeout. Used by unit tests.
162  void set_request_timeout_for_testing(const base::TimeDelta& timeout) {
163    request_timeout_for_testing_ = timeout;
164    request_timeout_for_testing_initialized_ = true;
165  }
166
167  // Returns delay before next portal check. Used by unit tests.
168  const base::TimeDelta& next_attempt_delay_for_testing() const {
169    return next_attempt_delay_;
170  }
171
172  // Sets current test time ticks. Used by unit tests.
173  void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
174    time_ticks_for_testing_ = time_ticks;
175  }
176
177  // Advances current test time ticks. Used by unit tests.
178  void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
179    time_ticks_for_testing_ += delta;
180  }
181
182  // Returns true if detection timeout callback isn't fired or
183  // cancelled.
184  bool DetectionTimeoutIsCancelledForTesting() const;
185
186  // Returns timeout for current (or immediate) detection attempt.
187  // The following rules are used for timeout computation:
188  // * if default (active) network is NULL, kBaseRequestTimeoutSec is used
189  // * if lazy detection mode is enabled, kLazyRequestTimeoutSec is used
190  // * otherwise, timeout equals to |attempt_count_| * kBaseRequestTimeoutSec
191  int GetRequestTimeoutSec() const;
192
193  // Unique identifier of the default network.
194  std::string default_network_id_;
195
196  // Service path of the default network.
197  std::string default_service_path_;
198
199  // Connection state of the default network.
200  std::string default_connection_state_;
201
202  State state_;
203  CaptivePortalStateMap portal_state_map_;
204  ObserverList<Observer> observers_;
205
206  base::CancelableClosure detection_task_;
207  base::CancelableClosure detection_timeout_;
208
209  // URL that returns a 204 response code when connected to the Internet.
210  GURL test_url_;
211
212  // Detector for checking default network for a portal state.
213  scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
214
215  // True if the NetworkPortalDetector is enabled.
216  bool enabled_;
217
218  base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_ptr_factory_;
219
220  // Number of portal detection attemps for a default network.
221  int attempt_count_;
222
223  bool lazy_detection_enabled_;
224
225  // Time between consecutive portal checks for a network in lazy
226  // mode.
227  base::TimeDelta lazy_check_interval_;
228
229  // Minimum time between consecutive portal checks for the same
230  // default network.
231  base::TimeDelta min_time_between_attempts_;
232
233  // Start time of portal detection.
234  base::TimeTicks detection_start_time_;
235
236  // Start time of portal detection attempt.
237  base::TimeTicks attempt_start_time_;
238
239  // Delay before next portal detection.
240  base::TimeDelta next_attempt_delay_;
241
242  // Test time ticks used by unit tests.
243  base::TimeTicks time_ticks_for_testing_;
244
245  // Test timeout for a portal detection used by unit tests.
246  base::TimeDelta request_timeout_for_testing_;
247
248  // True if |request_timeout_for_testing_| is initialized.
249  bool request_timeout_for_testing_initialized_;
250
251  content::NotificationRegistrar registrar_;
252
253  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
254};
255
256}  // namespace chromeos
257
258#endif  // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
259