network_portal_detector_impl.h revision 010d83a9304c5a91596085d917d248abff47903a
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_detector.h"
21#include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
22#include "chrome/browser/chromeos/net/network_portal_notification_controller.h"
23#include "chromeos/network/network_state_handler_observer.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  explicit NetworkPortalDetectorImpl(
64      const scoped_refptr<net::URLRequestContextGetter>& request_context);
65  virtual ~NetworkPortalDetectorImpl();
66
67  // NetworkPortalDetector implementation:
68  virtual void AddObserver(Observer* observer) OVERRIDE;
69  virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
70  virtual void RemoveObserver(Observer* observer) OVERRIDE;
71  virtual CaptivePortalState GetCaptivePortalState(
72      const std::string& service_path) OVERRIDE;
73  virtual bool IsEnabled() OVERRIDE;
74  virtual void Enable(bool start_detection) OVERRIDE;
75  virtual bool StartDetectionIfIdle() OVERRIDE;
76  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
77
78  // NetworkStateHandlerObserver implementation:
79  virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
80
81  // PortalDetectorStrategy::Delegate implementation:
82  virtual int AttemptCount() OVERRIDE;
83  virtual base::TimeTicks AttemptStartTime() OVERRIDE;
84  virtual base::TimeTicks GetCurrentTimeTicks() OVERRIDE;
85
86 private:
87  friend class NetworkPortalDetectorImplTest;
88  friend class NetworkPortalDetectorImplBrowserTest;
89
90  typedef std::string NetworkId;
91  typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
92
93  enum State {
94    // No portal check is running.
95    STATE_IDLE = 0,
96    // Waiting for portal check.
97    STATE_PORTAL_CHECK_PENDING,
98    // Portal check is in progress.
99    STATE_CHECKING_FOR_PORTAL,
100  };
101
102  // Starts detection process.
103  void StartDetection();
104
105  // Stops whole detection process.
106  void StopDetection();
107
108  // Internal predicate which describes set of states from which
109  // DetectCaptivePortal() can be called.
110  bool CanPerformAttempt() const;
111
112  // Initiates Captive Portal detection attempt after |delay|.
113  // You should check CanPerformAttempt() before calling this method.
114  void ScheduleAttempt(const base::TimeDelta& delay);
115
116  // Starts detection attempt.
117  void StartAttempt();
118
119  // Called when portal check is timed out. Cancels portal check and calls
120  // OnPortalDetectionCompleted() with RESULT_NO_RESPONSE as a result.
121  void OnAttemptTimeout();
122
123  // Called by CaptivePortalDetector when detection attempt completes.
124  void OnAttemptCompleted(
125      const captive_portal::CaptivePortalDetector::Results& results);
126
127  // content::NotificationObserver implementation:
128  virtual void Observe(int type,
129                       const content::NotificationSource& source,
130                       const content::NotificationDetails& details) OVERRIDE;
131
132  // Stores captive portal state for a |network| and notifies observers.
133  void OnDetectionCompleted(const NetworkState* network,
134                            const CaptivePortalState& results);
135
136  // Notifies observers that portal detection is completed for a |network|.
137  void NotifyDetectionCompleted(const NetworkState* network,
138                                const CaptivePortalState& state);
139
140  State state() const { return state_; }
141
142  bool is_idle() const {
143    return state_ == STATE_IDLE;
144  }
145  bool is_portal_check_pending() const {
146    return state_ == STATE_PORTAL_CHECK_PENDING;
147  }
148  bool is_checking_for_portal() const {
149    return state_ == STATE_CHECKING_FOR_PORTAL;
150  }
151
152  int attempt_count_for_testing() {
153    return attempt_count_;
154  }
155
156  void set_attempt_count_for_testing(int attempt_count) {
157    attempt_count_ = attempt_count;
158  }
159
160  // Returns delay before next portal check. Used by unit tests.
161  const base::TimeDelta& next_attempt_delay_for_testing() const {
162    return next_attempt_delay_;
163  }
164
165  // Returns true if attempt timeout callback isn't fired or
166  // cancelled.
167  bool AttemptTimeoutIsCancelledForTesting() const;
168
169  // Record detection stats such as detection duration and detection
170  // result in UMA.
171  void RecordDetectionStats(const NetworkState* network,
172                            CaptivePortalStatus status);
173
174  // Sets current test time ticks. Used by unit tests.
175  void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
176    time_ticks_for_testing_ = time_ticks;
177  }
178
179  // Advances current test time ticks. Used by unit tests.
180  void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
181    time_ticks_for_testing_ += delta;
182  }
183
184  // Name of the default network.
185  std::string default_network_name_;
186
187  // Unique identifier of the default network.
188  std::string default_network_id_;
189
190  // Service path of the default network.
191  std::string default_service_path_;
192
193  // Connection state of the default network.
194  std::string default_connection_state_;
195
196  State state_;
197  CaptivePortalStateMap portal_state_map_;
198  ObserverList<Observer> observers_;
199
200  base::CancelableClosure attempt_task_;
201  base::CancelableClosure attempt_timeout_;
202
203  // URL that returns a 204 response code when connected to the Internet.
204  GURL test_url_;
205
206  // Detector for checking default network for a portal state.
207  scoped_ptr<captive_portal::CaptivePortalDetector> captive_portal_detector_;
208
209  // True if the NetworkPortalDetector is enabled.
210  bool enabled_;
211
212  base::WeakPtrFactory<NetworkPortalDetectorImpl> weak_factory_;
213
214  // Start time of portal detection.
215  base::TimeTicks detection_start_time_;
216
217  // Start time of detection attempt.
218  base::TimeTicks attempt_start_time_;
219
220  // Number of already performed detection attempts.
221  int attempt_count_;
222
223  // Delay before next portal detection.
224  base::TimeDelta next_attempt_delay_;
225
226  // Current detection strategy.
227  scoped_ptr<PortalDetectorStrategy> strategy_;
228
229  // UI notification controller about captive portal state.
230  NetworkPortalNotificationController notification_controller_;
231
232  content::NotificationRegistrar registrar_;
233
234  // Test time ticks used by unit tests.
235  base::TimeTicks time_ticks_for_testing_;
236
237  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImpl);
238};
239
240}  // namespace chromeos
241
242#endif  // CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_
243