• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 namespace net {
32 class URLRequestContextGetter;
33 }
34 
35 namespace chromeos {
36 
37 class 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.
42 class 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 
state()140   State state() const { return state_; }
141 
is_idle()142   bool is_idle() const {
143     return state_ == STATE_IDLE;
144   }
is_portal_check_pending()145   bool is_portal_check_pending() const {
146     return state_ == STATE_PORTAL_CHECK_PENDING;
147   }
is_checking_for_portal()148   bool is_checking_for_portal() const {
149     return state_ == STATE_CHECKING_FOR_PORTAL;
150   }
151 
attempt_count_for_testing()152   int attempt_count_for_testing() {
153     return attempt_count_;
154   }
155 
set_attempt_count_for_testing(int attempt_count)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.
next_attempt_delay_for_testing()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.
set_time_ticks_for_testing(const base::TimeTicks & time_ticks)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.
advance_time_ticks_for_testing(const base::TimeDelta & delta)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