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