OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/gcm_driver/gcm_channel_status_syncer.h" | 5 #include "components/gcm_driver/gcm_channel_status_syncer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | |
8 #include "base/location.h" | 9 #include "base/location.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
11 #include "base/prefs/pref_registry_simple.h" | 12 #include "base/prefs/pref_registry_simple.h" |
12 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
15 #include "base/strings/string_number_conversions.h" | |
14 #include "components/gcm_driver/gcm_channel_status_request.h" | 16 #include "components/gcm_driver/gcm_channel_status_request.h" |
15 #include "components/gcm_driver/gcm_driver.h" | 17 #include "components/gcm_driver/gcm_driver.h" |
16 #include "components/pref_registry/pref_registry_syncable.h" | 18 #include "components/pref_registry/pref_registry_syncable.h" |
17 | 19 |
18 namespace gcm { | 20 namespace gcm { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // The GCM channel's enabled state. | 24 // The GCM channel's enabled state. |
23 const char kGCMChannelStatus[] = "gcm.channel_status"; | 25 const char kGCMChannelStatus[] = "gcm.channel_status"; |
24 | 26 |
25 // The GCM channel's polling interval (in seconds). | 27 // The GCM channel's polling interval (in seconds). |
26 const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; | 28 const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; |
27 | 29 |
28 // Last time when checking with the GCM channel status server is done. | 30 // Last time when checking with the GCM channel status server is done. |
29 const char kGCMChannelLastCheckTime[] = "gcm.check_time"; | 31 const char kGCMChannelLastCheckTime[] = "gcm.check_time"; |
30 | 32 |
31 // A small delay to avoid sending request at browser startup time for first-time | 33 // A small delay to avoid sending request at browser startup time for first-time |
32 // request. | 34 // request. |
33 const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. | 35 const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. |
34 | 36 |
35 // The fuzzing variation added to the polling delay. | 37 // The fuzzing variation added to the polling delay. |
36 const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues. | 38 const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues. |
37 | 39 |
40 // The minimum poll interval that can be overridden to. | |
41 const int kMinCustomPollIntervalMinutes = 5; | |
42 | |
43 // Custom poll interval could not be used more than the number below. | |
44 const int kMaxNumberToUseCustomPollInterval = 5; | |
45 | |
38 } // namespace | 46 } // namespace |
39 | 47 |
48 namespace switches { | |
49 | |
50 // Override the default poll interval for testing purpose. | |
51 const char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval"; | |
52 | |
53 } // namepsace switches | |
54 | |
40 // static | 55 // static |
41 void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { | 56 void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { |
42 registry->RegisterBooleanPref(kGCMChannelStatus, true); | 57 registry->RegisterBooleanPref(kGCMChannelStatus, true); |
43 registry->RegisterIntegerPref( | 58 registry->RegisterIntegerPref( |
44 kGCMChannelPollIntervalSeconds, | 59 kGCMChannelPollIntervalSeconds, |
45 GCMChannelStatusRequest::default_poll_interval_seconds()); | 60 GCMChannelStatusRequest::default_poll_interval_seconds()); |
46 registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0); | 61 registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0); |
47 } | 62 } |
48 | 63 |
49 // static | 64 // static |
(...skipping 25 matching lines...) Expand all Loading... | |
75 const std::string& user_agent, | 90 const std::string& user_agent, |
76 const scoped_refptr<net::URLRequestContextGetter>& request_context) | 91 const scoped_refptr<net::URLRequestContextGetter>& request_context) |
77 : driver_(driver), | 92 : driver_(driver), |
78 prefs_(prefs), | 93 prefs_(prefs), |
79 channel_status_request_url_(channel_status_request_url), | 94 channel_status_request_url_(channel_status_request_url), |
80 user_agent_(user_agent), | 95 user_agent_(user_agent), |
81 request_context_(request_context), | 96 request_context_(request_context), |
82 gcm_enabled_(true), | 97 gcm_enabled_(true), |
83 poll_interval_seconds_( | 98 poll_interval_seconds_( |
84 GCMChannelStatusRequest::default_poll_interval_seconds()), | 99 GCMChannelStatusRequest::default_poll_interval_seconds()), |
100 custom_poll_interval_use_count_(0), | |
85 delay_removed_for_testing_(false), | 101 delay_removed_for_testing_(false), |
86 weak_ptr_factory_(this) { | 102 weak_ptr_factory_(this) { |
87 gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus); | 103 gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus); |
88 poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds); | 104 poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds); |
89 if (poll_interval_seconds_ < | 105 if (poll_interval_seconds_ < |
90 GCMChannelStatusRequest::min_poll_interval_seconds()) { | 106 GCMChannelStatusRequest::min_poll_interval_seconds()) { |
91 poll_interval_seconds_ = | 107 poll_interval_seconds_ = |
92 GCMChannelStatusRequest::min_poll_interval_seconds(); | 108 GCMChannelStatusRequest::min_poll_interval_seconds(); |
93 } | 109 } |
110 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
111 switches::kCustomPollIntervalMinutes)) { | |
112 std::string value(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
113 switches::kCustomPollIntervalMinutes)); | |
114 int minutes = 0; | |
115 if (base::StringToInt(value, &minutes) && | |
116 minutes >= kMinCustomPollIntervalMinutes) { | |
117 poll_interval_seconds_ = minutes * 60; | |
118 custom_poll_interval_use_count_ = kMaxNumberToUseCustomPollInterval; | |
119 } | |
fgorski
2014/10/15 21:17:20
nit: DVLOG here that it was not set and we are ign
| |
120 } | |
94 last_check_time_ = base::Time::FromInternalValue( | 121 last_check_time_ = base::Time::FromInternalValue( |
95 prefs_->GetInt64(kGCMChannelLastCheckTime)); | 122 prefs_->GetInt64(kGCMChannelLastCheckTime)); |
96 } | 123 } |
97 | 124 |
98 GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { | 125 GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { |
99 } | 126 } |
100 | 127 |
101 void GCMChannelStatusSyncer::EnsureStarted() { | 128 void GCMChannelStatusSyncer::EnsureStarted() { |
102 // Bail out if the request is already scheduled or started. | 129 // Bail out if the request is already scheduled or started. |
103 if (weak_ptr_factory_.HasWeakPtrs() || request_) | 130 if (weak_ptr_factory_.HasWeakPtrs() || request_) |
104 return; | 131 return; |
105 | 132 |
106 ScheduleRequest(); | 133 ScheduleRequest(); |
107 } | 134 } |
108 | 135 |
109 void GCMChannelStatusSyncer::Stop() { | 136 void GCMChannelStatusSyncer::Stop() { |
110 request_.reset(); | 137 request_.reset(); |
111 weak_ptr_factory_.InvalidateWeakPtrs(); | 138 weak_ptr_factory_.InvalidateWeakPtrs(); |
112 } | 139 } |
113 | 140 |
114 void GCMChannelStatusSyncer::OnRequestCompleted(bool enabled, | 141 void GCMChannelStatusSyncer::OnRequestCompleted(bool update_received, |
142 bool enabled, | |
115 int poll_interval_seconds) { | 143 int poll_interval_seconds) { |
116 DCHECK(request_); | 144 DCHECK(request_); |
117 request_.reset(); | 145 request_.reset(); |
118 | 146 |
119 // Persist the current time as the last request complete time. | 147 // Persist the current time as the last request complete time. |
120 last_check_time_ = base::Time::Now(); | 148 last_check_time_ = base::Time::Now(); |
121 prefs_->SetInt64(kGCMChannelLastCheckTime, | 149 prefs_->SetInt64(kGCMChannelLastCheckTime, |
122 last_check_time_.ToInternalValue()); | 150 last_check_time_.ToInternalValue()); |
123 | 151 |
124 if (gcm_enabled_ != enabled) { | 152 if (update_received) { |
125 gcm_enabled_ = enabled; | 153 if (gcm_enabled_ != enabled) { |
126 prefs_->SetBoolean(kGCMChannelStatus, enabled); | 154 gcm_enabled_ = enabled; |
127 if (gcm_enabled_) | 155 prefs_->SetBoolean(kGCMChannelStatus, enabled); |
128 driver_->Enable(); | 156 if (gcm_enabled_) |
129 else | 157 driver_->Enable(); |
130 driver_->Disable(); | 158 else |
131 } | 159 driver_->Disable(); |
160 } | |
132 | 161 |
133 DCHECK_GE(poll_interval_seconds, | 162 DCHECK_GE(poll_interval_seconds, |
134 GCMChannelStatusRequest::min_poll_interval_seconds()); | 163 GCMChannelStatusRequest::min_poll_interval_seconds()); |
135 if (poll_interval_seconds_ != poll_interval_seconds) { | 164 if (poll_interval_seconds_ != poll_interval_seconds) { |
136 poll_interval_seconds_ = poll_interval_seconds; | 165 poll_interval_seconds_ = poll_interval_seconds; |
137 prefs_->SetInteger(kGCMChannelPollIntervalSeconds, poll_interval_seconds_); | 166 prefs_->SetInteger(kGCMChannelPollIntervalSeconds, |
167 poll_interval_seconds_); | |
168 } | |
138 } | 169 } |
139 | 170 |
140 ScheduleRequest(); | 171 ScheduleRequest(); |
141 } | 172 } |
142 | 173 |
143 void GCMChannelStatusSyncer::ScheduleRequest() { | 174 void GCMChannelStatusSyncer::ScheduleRequest() { |
144 current_request_delay_interval_ = GetRequestDelayInterval(); | 175 current_request_delay_interval_ = GetRequestDelayInterval(); |
145 base::MessageLoop::current()->PostDelayedTask( | 176 base::MessageLoop::current()->PostDelayedTask( |
146 FROM_HERE, | 177 FROM_HERE, |
147 base::Bind(&GCMChannelStatusSyncer::StartRequest, | 178 base::Bind(&GCMChannelStatusSyncer::StartRequest, |
(...skipping 25 matching lines...) Expand all Loading... | |
173 if (delay_seconds < 0) | 204 if (delay_seconds < 0) |
174 delay_seconds = 0; | 205 delay_seconds = 0; |
175 | 206 |
176 if (last_check_time_.is_null()) { | 207 if (last_check_time_.is_null()) { |
177 // For the first-time request, add a small delay to avoid sending request at | 208 // For the first-time request, add a small delay to avoid sending request at |
178 // browser startup time. | 209 // browser startup time. |
179 DCHECK(!delay_seconds); | 210 DCHECK(!delay_seconds); |
180 delay_seconds = kFirstTimeDelaySeconds; | 211 delay_seconds = kFirstTimeDelaySeconds; |
181 } else { | 212 } else { |
182 // Otherwise, add a fuzzing variation to the delay. | 213 // Otherwise, add a fuzzing variation to the delay. |
183 delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds); | 214 // The fuzzing variation is off when the custom interval is used. |
215 if (custom_poll_interval_use_count_) | |
216 custom_poll_interval_use_count_--; | |
217 else | |
218 delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds); | |
184 } | 219 } |
185 | 220 |
186 return base::TimeDelta::FromSeconds(delay_seconds); | 221 return base::TimeDelta::FromSeconds(delay_seconds); |
187 } | 222 } |
188 | 223 |
189 } // namespace gcm | 224 } // namespace gcm |
OLD | NEW |