- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / captive_portal / captive_portal_service.h
1 // Copyright (c) 2012 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_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_
6 #define CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_
7
8 #include "base/basictypes.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/pref_member.h"
11 #include "base/threading/non_thread_safe.h"
12 #include "base/time/time.h"
13 #include "base/timer/timer.h"
14 #include "chrome/browser/captive_portal/captive_portal_detector.h"
15 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
16 #include "net/base/backoff_entry.h"
17 #include "url/gurl.h"
18
19 class Profile;
20
21 namespace captive_portal {
22
23 // Service that checks for captive portals when queried, and sends a
24 // NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT with the Profile as the source and
25 // a CaptivePortalService::Results as the details.
26 //
27 // Captive portal checks are rate-limited.  The CaptivePortalService may only
28 // be accessed on the UI thread.
29 // Design doc: https://docs.google.com/document/d/1k-gP2sswzYNvryu9NcgN7q5XrsMlUdlUdoW9WRaEmfM/edit
30 class CaptivePortalService : public BrowserContextKeyedService,
31                              public base::NonThreadSafe {
32  public:
33   enum TestingState {
34     NOT_TESTING,
35     DISABLED_FOR_TESTING,  // The service is always disabled.
36     SKIP_OS_CHECK_FOR_TESTING  // The service can be enabled even if the OS has
37                                // native captive portal detection.
38   };
39
40   // The details sent via a NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT.
41   struct Results {
42     // The result of the second most recent captive portal check.
43     Result previous_result;
44     // The result of the most recent captive portal check.
45     Result result;
46   };
47
48   explicit CaptivePortalService(Profile* profile);
49   virtual ~CaptivePortalService();
50
51   // Triggers a check for a captive portal.  If there's already a check in
52   // progress, does nothing.  Throttles the rate at which requests are sent.
53   // Always sends the result notification asynchronously.
54   void DetectCaptivePortal();
55
56   // Returns the URL used for captive portal testing.  When a captive portal is
57   // detected, this URL will take us to the captive portal landing page.
58   const GURL& test_url() const { return test_url_; }
59
60   // Result of the most recent captive portal check.
61   Result last_detection_result() const { return last_detection_result_; }
62
63   // Whether or not the CaptivePortalService is enabled.  When disabled, all
64   // checks return INTERNET_CONNECTED.
65   bool enabled() const { return enabled_; }
66
67   // Used to disable captive portal detection so it doesn't interfere with
68   // tests.  Should be called before the service is created.
69   static void set_state_for_testing(TestingState testing_state) {
70     testing_state_ = testing_state;
71   }
72   static TestingState get_state_for_testing() { return testing_state_; }
73
74  private:
75   friend class CaptivePortalServiceTest;
76   friend class CaptivePortalBrowserTest;
77
78   // Subclass of BackoffEntry that uses the CaptivePortalService's
79   // GetCurrentTime function, for unit testing.
80   class RecheckBackoffEntry;
81
82   enum State {
83     // No check is running or pending.
84     STATE_IDLE,
85     // The timer to check for a captive portal is running.
86     STATE_TIMER_RUNNING,
87     // There's an outstanding HTTP request to check for a captive portal.
88     STATE_CHECKING_FOR_PORTAL,
89   };
90
91   // Contains all the information about the minimum time allowed between two
92   // consecutive captive portal checks.
93   struct RecheckPolicy {
94     // Constructor initializes all values to defaults.
95     RecheckPolicy();
96
97     // The minimum amount of time between two captive portal checks, when the
98     // last check found no captive portal.
99     int initial_backoff_no_portal_ms;
100
101     // The minimum amount of time between two captive portal checks, when the
102     // last check found a captive portal.  This is expected to be less than
103     // |initial_backoff_no_portal_ms|.  Also used when the service is disabled.
104     int initial_backoff_portal_ms;
105
106     net::BackoffEntry::Policy backoff_policy;
107   };
108
109   // Initiates a captive portal check, without any throttling.  If the service
110   // is disabled, just acts like there's an Internet connection.
111   void DetectCaptivePortalInternal();
112
113   // Called by CaptivePortalDetector when detection completes.
114   void OnPortalDetectionCompleted(
115       const CaptivePortalDetector::Results& results);
116
117   // BrowserContextKeyedService:
118   virtual void Shutdown() OVERRIDE;
119
120   // Called when a captive portal check completes.  Passes the result to all
121   // observers.
122   void OnResult(Result result);
123
124   // Updates BackoffEntry::Policy and creates a new BackoffEntry, which
125   // resets the count used for throttling.
126   void ResetBackoffEntry(Result result);
127
128   // Updates |enabled_| based on command line flags and Profile preferences,
129   // and sets |state_| to STATE_NONE if it's false.
130   // TODO(mmenke): Figure out on which platforms, if any, should not use
131   //               automatic captive portal detection.  Currently it's enabled
132   //               on all platforms, though this code is not compiled on
133   //               Android, since it lacks the Browser class.
134   void UpdateEnabledState();
135
136   // Returns the current TimeTicks.
137   base::TimeTicks GetCurrentTimeTicks() const;
138
139   bool DetectionInProgress() const;
140
141   // Returns true if the timer to try and detect a captive portal is running.
142   bool TimerRunning() const;
143
144   State state() const { return state_; }
145
146   RecheckPolicy& recheck_policy() { return recheck_policy_; }
147
148   void set_test_url(const GURL& test_url) { test_url_ = test_url; }
149
150   // Sets current test time ticks. Used by unit tests.
151   void set_time_ticks_for_testing(const base::TimeTicks& time_ticks) {
152     time_ticks_for_testing_ = time_ticks;
153   }
154
155   // Advances current test time ticks. Used by unit tests.
156   void advance_time_ticks_for_testing(const base::TimeDelta& delta) {
157     time_ticks_for_testing_ += delta;
158   }
159
160   // The profile that owns this CaptivePortalService.
161   Profile* profile_;
162
163   State state_;
164
165   // Detector for checking active network for a portal state.
166   CaptivePortalDetector captive_portal_detector_;
167
168   // True if the service is enabled.  When not enabled, all checks will return
169   // RESULT_INTERNET_CONNECTED.
170   bool enabled_;
171
172   // The result of the most recent captive portal check.
173   Result last_detection_result_;
174
175   // Number of sequential checks with the same captive portal result.
176   int num_checks_with_same_result_;
177
178   // Time when |last_detection_result_| was first received.
179   base::TimeTicks first_check_time_with_same_result_;
180
181   // Time the last captive portal check completed.
182   base::TimeTicks last_check_time_;
183
184   // Policy for throttling portal checks.
185   RecheckPolicy recheck_policy_;
186
187   // Implements behavior needed by |recheck_policy_|.  Whenever there's a new
188   // captive_portal::Result, BackoffEntry::Policy is updated and
189   // |backoff_entry_| is recreated.  Each check that returns the same Result
190   // is considered a "failure", to trigger throttling.
191   scoped_ptr<net::BackoffEntry> backoff_entry_;
192
193   // URL that returns a 204 response code when connected to the Internet.
194   GURL test_url_;
195
196   // The pref member for whether navigation errors should be resolved with a web
197   // service.  Actually called "alternate_error_pages", since it's also used for
198   // the Link Doctor.
199   BooleanPrefMember resolve_errors_with_web_service_;
200
201   base::OneShotTimer<CaptivePortalService> check_captive_portal_timer_;
202
203   static TestingState testing_state_;
204
205   // Test time ticks used by unit tests.
206   base::TimeTicks time_ticks_for_testing_;
207
208   DISALLOW_COPY_AND_ASSIGN(CaptivePortalService);
209 };
210
211 }  // namespace captive_portal
212
213 #endif  // CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_