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