Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / captive_portal / captive_portal_service.h
blobdbe07de02c29f4d6321f60539f8cdf5b7d5b3b74
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.
5 #ifndef CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_
6 #define CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_
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/tick_clock.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "components/captive_portal/captive_portal_detector.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 #include "net/base/backoff_entry.h"
18 #include "url/gurl.h"
20 class Profile;
22 // Service that checks for captive portals when queried, and sends a
23 // NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT with the Profile as the source and
24 // a CaptivePortalService::Results as the details.
26 // Captive portal checks are rate-limited. The CaptivePortalService may only
27 // be accessed on the UI thread.
28 // Design doc: https://docs.google.com/document/d/1k-gP2sswzYNvryu9NcgN7q5XrsMlUdlUdoW9WRaEmfM/edit
29 class CaptivePortalService : public KeyedService, public base::NonThreadSafe {
30 public:
31 enum TestingState {
32 NOT_TESTING,
33 DISABLED_FOR_TESTING, // The service is always disabled.
34 SKIP_OS_CHECK_FOR_TESTING, // The service can be enabled even if the OS
35 // has native captive portal detection.
36 IGNORE_REQUESTS_FOR_TESTING // Disables actual portal checks. This also
37 // implies SKIP_OS_CHECK_FOR_TESTING.
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 captive_portal::CaptivePortalResult previous_result;
44 // The result of the most recent captive portal check.
45 captive_portal::CaptivePortalResult result;
46 // Landing url of the captive portal check ping. If behind a captive portal,
47 // this points to the login page.
48 GURL landing_url;
51 explicit CaptivePortalService(Profile* profile);
52 CaptivePortalService(Profile* profile, base::TickClock* clock_for_testing);
53 ~CaptivePortalService() override;
55 // Triggers a check for a captive portal. If there's already a check in
56 // progress, does nothing. Throttles the rate at which requests are sent.
57 // Always sends the result notification asynchronously.
58 void DetectCaptivePortal();
60 // Returns the URL used for captive portal testing. When a captive portal is
61 // detected, this URL will take us to the captive portal landing page.
62 const GURL& test_url() const { return test_url_; }
64 // Result of the most recent captive portal check.
65 captive_portal::CaptivePortalResult last_detection_result() const {
66 return last_detection_result_;
69 // Whether or not the CaptivePortalService is enabled. When disabled, all
70 // checks return INTERNET_CONNECTED.
71 bool enabled() const { return enabled_; }
73 // Used to disable captive portal detection so it doesn't interfere with
74 // tests. Should be called before the service is created.
75 static void set_state_for_testing(TestingState testing_state) {
76 testing_state_ = testing_state;
78 static TestingState get_state_for_testing() { return testing_state_; }
80 private:
81 friend class CaptivePortalServiceTest;
82 friend class CaptivePortalBrowserTest;
84 enum State {
85 // No check is running or pending.
86 STATE_IDLE,
87 // The timer to check for a captive portal is running.
88 STATE_TIMER_RUNNING,
89 // There's an outstanding HTTP request to check for a captive portal.
90 STATE_CHECKING_FOR_PORTAL,
93 // Contains all the information about the minimum time allowed between two
94 // consecutive captive portal checks.
95 struct RecheckPolicy {
96 // Constructor initializes all values to defaults.
97 RecheckPolicy();
99 // The minimum amount of time between two captive portal checks, when the
100 // last check found no captive portal.
101 int initial_backoff_no_portal_ms;
103 // The minimum amount of time between two captive portal checks, when the
104 // last check found a captive portal. This is expected to be less than
105 // |initial_backoff_no_portal_ms|. Also used when the service is disabled.
106 int initial_backoff_portal_ms;
108 net::BackoffEntry::Policy backoff_policy;
111 // Initiates a captive portal check, without any throttling. If the service
112 // is disabled, just acts like there's an Internet connection.
113 void DetectCaptivePortalInternal();
115 // Called by CaptivePortalDetector when detection completes.
116 void OnPortalDetectionCompleted(
117 const captive_portal::CaptivePortalDetector::Results& results);
119 // KeyedService:
120 void Shutdown() override;
122 // Called when a captive portal check completes. Passes the result to all
123 // observers.
124 void OnResult(captive_portal::CaptivePortalResult result,
125 const GURL& landing_url);
127 // Updates BackoffEntry::Policy and creates a new BackoffEntry, which
128 // resets the count used for throttling.
129 void ResetBackoffEntry(captive_portal::CaptivePortalResult result);
131 // Updates |enabled_| based on command line flags and Profile preferences,
132 // and sets |state_| to STATE_NONE if it's false.
133 // TODO(mmenke): Figure out on which platforms, if any, should not use
134 // automatic captive portal detection. Currently it's enabled
135 // on all platforms, though this code is not compiled on
136 // Android, since it lacks the Browser class.
137 void UpdateEnabledState();
139 base::TimeTicks GetCurrentTimeTicks() const;
141 bool DetectionInProgress() const;
143 // Returns true if the timer to try and detect a captive portal is running.
144 bool TimerRunning() const;
146 State state() const { return state_; }
148 RecheckPolicy& recheck_policy() { return recheck_policy_; }
150 void set_test_url(const GURL& test_url) { test_url_ = test_url; }
152 // The profile that owns this CaptivePortalService.
153 Profile* profile_;
155 State state_;
157 // Detector for checking active network for a portal state.
158 captive_portal::CaptivePortalDetector captive_portal_detector_;
160 // True if the service is enabled. When not enabled, all checks will return
161 // RESULT_INTERNET_CONNECTED.
162 bool enabled_;
164 // The result of the most recent captive portal check.
165 captive_portal::CaptivePortalResult last_detection_result_;
167 // Number of sequential checks with the same captive portal result.
168 int num_checks_with_same_result_;
170 // Time when |last_detection_result_| was first received.
171 base::TimeTicks first_check_time_with_same_result_;
173 // Time the last captive portal check completed.
174 base::TimeTicks last_check_time_;
176 // Policy for throttling portal checks.
177 RecheckPolicy recheck_policy_;
179 // Implements behavior needed by |recheck_policy_|. Whenever there's a new
180 // captive_portal::CaptivePortalResult, BackoffEntry::Policy is updated and
181 // |backoff_entry_| is recreated. Each check that returns the same result
182 // is considered a "failure", to trigger throttling.
183 scoped_ptr<net::BackoffEntry> backoff_entry_;
185 // URL that returns a 204 response code when connected to the Internet.
186 GURL test_url_;
188 // The pref member for whether navigation errors should be resolved with a web
189 // service. Actually called "alternate_error_pages", since it's also used for
190 // the Link Doctor.
191 BooleanPrefMember resolve_errors_with_web_service_;
193 base::OneShotTimer<CaptivePortalService> check_captive_portal_timer_;
195 static TestingState testing_state_;
197 // Test tick clock used by unit tests.
198 base::TickClock* tick_clock_for_testing_; // Not owned.
200 DISALLOW_COPY_AND_ASSIGN(CaptivePortalService);
203 #endif // CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_SERVICE_H_