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/command_line.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/prefs/pref_registry_simple.h" | 12 #include "base/prefs/pref_registry_simple.h" |
13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
14 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
16 #include "components/gcm_driver/gcm_channel_status_request.h" | 16 #include "components/gcm_driver/gcm_channel_status_request.h" |
17 #include "components/gcm_driver/gcm_driver.h" | 17 #include "components/gcm_driver/gcm_driver.h" |
18 #include "components/pref_registry/pref_registry_syncable.h" | 18 #include "components/pref_registry/pref_registry_syncable.h" |
19 | 19 |
20 namespace gcm { | 20 namespace gcm { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // The GCM channel's enabled state. | |
25 const char kGCMChannelStatus[] = "gcm.channel_status"; | |
26 | |
27 // The GCM channel's polling interval (in seconds). | |
28 const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; | |
29 | |
30 // Last time when checking with the GCM channel status server is done. | |
31 const char kGCMChannelLastCheckTime[] = "gcm.check_time"; | |
32 | |
33 // A small delay to avoid sending request at browser startup time for first-time | 24 // A small delay to avoid sending request at browser startup time for first-time |
34 // request. | 25 // request. |
35 const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. | 26 const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. |
36 | 27 |
37 // The fuzzing variation added to the polling delay. | 28 // The fuzzing variation added to the polling delay. |
38 const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues. | 29 const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues. |
39 | 30 |
40 // The minimum poll interval that can be overridden to. | 31 // The minimum poll interval that can be overridden to. |
41 const int kMinCustomPollIntervalMinutes = 2; | 32 const int kMinCustomPollIntervalMinutes = 2; |
42 | 33 |
43 // Custom poll interval could not be used more than the limit below. | 34 // Custom poll interval could not be used more than the limit below. |
44 const int kMaxNumberToUseCustomPollInterval = 10; | 35 const int kMaxNumberToUseCustomPollInterval = 10; |
45 | 36 |
46 } // namespace | 37 } // namespace |
47 | 38 |
| 39 namespace prefs { |
| 40 |
| 41 // The GCM channel's enabled state. |
| 42 const char kGCMChannelStatus[] = "gcm.channel_status"; |
| 43 |
| 44 // The GCM channel's polling interval (in seconds). |
| 45 const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; |
| 46 |
| 47 // Last time when checking with the GCM channel status server is done. |
| 48 const char kGCMChannelLastCheckTime[] = "gcm.check_time"; |
| 49 |
| 50 } // namepsace prefs |
| 51 |
48 namespace switches { | 52 namespace switches { |
49 | 53 |
50 // Override the default poll interval for testing purpose. | 54 // Override the default poll interval for testing purpose. |
51 const char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval"; | 55 const char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval"; |
52 | 56 |
53 } // namepsace switches | 57 } // namepsace switches |
54 | 58 |
55 // static | 59 // static |
56 void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { | 60 void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { |
57 registry->RegisterBooleanPref(kGCMChannelStatus, true); | 61 registry->RegisterBooleanPref(prefs::kGCMChannelStatus, true); |
58 registry->RegisterIntegerPref( | 62 registry->RegisterIntegerPref( |
59 kGCMChannelPollIntervalSeconds, | 63 prefs::kGCMChannelPollIntervalSeconds, |
60 GCMChannelStatusRequest::default_poll_interval_seconds()); | 64 GCMChannelStatusRequest::default_poll_interval_seconds()); |
61 registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0); | 65 registry->RegisterInt64Pref(prefs::kGCMChannelLastCheckTime, 0); |
62 } | 66 } |
63 | 67 |
64 // static | 68 // static |
65 void GCMChannelStatusSyncer::RegisterProfilePrefs( | 69 void GCMChannelStatusSyncer::RegisterProfilePrefs( |
66 user_prefs::PrefRegistrySyncable* registry) { | 70 user_prefs::PrefRegistrySyncable* registry) { |
67 registry->RegisterBooleanPref( | 71 registry->RegisterBooleanPref( |
68 kGCMChannelStatus, | 72 prefs::kGCMChannelStatus, |
69 true, | 73 true, |
70 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 74 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
71 registry->RegisterIntegerPref( | 75 registry->RegisterIntegerPref( |
72 kGCMChannelPollIntervalSeconds, | 76 prefs::kGCMChannelPollIntervalSeconds, |
73 GCMChannelStatusRequest::default_poll_interval_seconds(), | 77 GCMChannelStatusRequest::default_poll_interval_seconds(), |
74 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 78 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
75 registry->RegisterInt64Pref( | 79 registry->RegisterInt64Pref( |
76 kGCMChannelLastCheckTime, | 80 prefs::kGCMChannelLastCheckTime, |
77 0, | 81 0, |
78 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 82 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
79 } | 83 } |
80 | 84 |
81 // static | 85 // static |
82 int GCMChannelStatusSyncer::first_time_delay_seconds() { | 86 int GCMChannelStatusSyncer::first_time_delay_seconds() { |
83 return kFirstTimeDelaySeconds; | 87 return kFirstTimeDelaySeconds; |
84 } | 88 } |
85 | 89 |
86 GCMChannelStatusSyncer::GCMChannelStatusSyncer( | 90 GCMChannelStatusSyncer::GCMChannelStatusSyncer( |
87 GCMDriver* driver, | 91 GCMDriver* driver, |
88 PrefService* prefs, | 92 PrefService* prefs, |
89 const std::string& channel_status_request_url, | 93 const std::string& channel_status_request_url, |
90 const std::string& user_agent, | 94 const std::string& user_agent, |
91 const scoped_refptr<net::URLRequestContextGetter>& request_context) | 95 const scoped_refptr<net::URLRequestContextGetter>& request_context) |
92 : driver_(driver), | 96 : driver_(driver), |
93 prefs_(prefs), | 97 prefs_(prefs), |
94 channel_status_request_url_(channel_status_request_url), | 98 channel_status_request_url_(channel_status_request_url), |
95 user_agent_(user_agent), | 99 user_agent_(user_agent), |
96 request_context_(request_context), | 100 request_context_(request_context), |
97 started_(false), | 101 started_(false), |
98 gcm_enabled_(true), | 102 gcm_enabled_(true), |
99 poll_interval_seconds_( | 103 poll_interval_seconds_( |
100 GCMChannelStatusRequest::default_poll_interval_seconds()), | 104 GCMChannelStatusRequest::default_poll_interval_seconds()), |
101 custom_poll_interval_use_count_(0), | 105 custom_poll_interval_use_count_(0), |
102 delay_removed_for_testing_(false), | 106 delay_removed_for_testing_(false), |
103 weak_ptr_factory_(this) { | 107 weak_ptr_factory_(this) { |
104 gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus); | 108 gcm_enabled_ = prefs_->GetBoolean(prefs::kGCMChannelStatus); |
105 poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds); | 109 poll_interval_seconds_ = prefs_->GetInteger( |
| 110 prefs::kGCMChannelPollIntervalSeconds); |
106 if (poll_interval_seconds_ < | 111 if (poll_interval_seconds_ < |
107 GCMChannelStatusRequest::min_poll_interval_seconds()) { | 112 GCMChannelStatusRequest::min_poll_interval_seconds()) { |
108 poll_interval_seconds_ = | 113 poll_interval_seconds_ = |
109 GCMChannelStatusRequest::min_poll_interval_seconds(); | 114 GCMChannelStatusRequest::min_poll_interval_seconds(); |
110 } | 115 } |
111 const base::CommandLine& command_line = | 116 const base::CommandLine& command_line = |
112 *base::CommandLine::ForCurrentProcess(); | 117 *base::CommandLine::ForCurrentProcess(); |
113 if (command_line.HasSwitch(switches::kCustomPollIntervalMinutes)) { | 118 if (command_line.HasSwitch(switches::kCustomPollIntervalMinutes)) { |
114 std::string value(command_line.GetSwitchValueASCII( | 119 std::string value(command_line.GetSwitchValueASCII( |
115 switches::kCustomPollIntervalMinutes)); | 120 switches::kCustomPollIntervalMinutes)); |
116 int minutes = 0; | 121 int minutes = 0; |
117 if (base::StringToInt(value, &minutes)) { | 122 if (base::StringToInt(value, &minutes)) { |
118 DCHECK_GE(minutes, kMinCustomPollIntervalMinutes); | 123 DCHECK_GE(minutes, kMinCustomPollIntervalMinutes); |
119 if (minutes >= kMinCustomPollIntervalMinutes) { | 124 if (minutes >= kMinCustomPollIntervalMinutes) { |
120 poll_interval_seconds_ = minutes * 60; | 125 poll_interval_seconds_ = minutes * 60; |
121 custom_poll_interval_use_count_ = kMaxNumberToUseCustomPollInterval; | 126 custom_poll_interval_use_count_ = kMaxNumberToUseCustomPollInterval; |
122 } | 127 } |
123 } | 128 } |
124 } | 129 } |
125 last_check_time_ = base::Time::FromInternalValue( | 130 last_check_time_ = base::Time::FromInternalValue( |
126 prefs_->GetInt64(kGCMChannelLastCheckTime)); | 131 prefs_->GetInt64(prefs::kGCMChannelLastCheckTime)); |
127 } | 132 } |
128 | 133 |
129 GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { | 134 GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { |
130 } | 135 } |
131 | 136 |
132 void GCMChannelStatusSyncer::EnsureStarted() { | 137 void GCMChannelStatusSyncer::EnsureStarted() { |
133 // Bail out if the request is already scheduled or started. | 138 // Bail out if the request is already scheduled or started. |
134 if (started_) | 139 if (started_) |
135 return; | 140 return; |
136 started_ = true; | 141 started_ = true; |
137 | 142 |
138 ScheduleRequest(); | 143 ScheduleRequest(); |
139 } | 144 } |
140 | 145 |
141 void GCMChannelStatusSyncer::Stop() { | 146 void GCMChannelStatusSyncer::Stop() { |
142 started_ = false; | 147 started_ = false; |
143 request_.reset(); | 148 request_.reset(); |
144 weak_ptr_factory_.InvalidateWeakPtrs(); | 149 weak_ptr_factory_.InvalidateWeakPtrs(); |
145 } | 150 } |
146 | 151 |
147 void GCMChannelStatusSyncer::OnRequestCompleted(bool update_received, | 152 void GCMChannelStatusSyncer::OnRequestCompleted(bool update_received, |
148 bool enabled, | 153 bool enabled, |
149 int poll_interval_seconds) { | 154 int poll_interval_seconds) { |
150 DCHECK(request_); | 155 DCHECK(request_); |
151 request_.reset(); | 156 request_.reset(); |
152 | 157 |
153 // Persist the current time as the last request complete time. | 158 // Persist the current time as the last request complete time. |
154 last_check_time_ = base::Time::Now(); | 159 last_check_time_ = base::Time::Now(); |
155 prefs_->SetInt64(kGCMChannelLastCheckTime, | 160 prefs_->SetInt64(prefs::kGCMChannelLastCheckTime, |
156 last_check_time_.ToInternalValue()); | 161 last_check_time_.ToInternalValue()); |
157 | 162 |
158 if (update_received) { | 163 if (update_received) { |
159 if (gcm_enabled_ != enabled) { | 164 if (gcm_enabled_ != enabled) { |
160 gcm_enabled_ = enabled; | 165 gcm_enabled_ = enabled; |
161 prefs_->SetBoolean(kGCMChannelStatus, enabled); | 166 prefs_->SetBoolean(prefs::kGCMChannelStatus, enabled); |
162 if (gcm_enabled_) | 167 if (gcm_enabled_) |
163 driver_->Enable(); | 168 driver_->Enable(); |
164 else | 169 else |
165 driver_->Disable(); | 170 driver_->Disable(); |
166 } | 171 } |
167 | 172 |
168 // Skip updating poll interval if the custom one is still in effect. | 173 // Skip updating poll interval if the custom one is still in effect. |
169 if (!custom_poll_interval_use_count_) { | 174 if (!custom_poll_interval_use_count_) { |
170 DCHECK_GE(poll_interval_seconds, | 175 DCHECK_GE(poll_interval_seconds, |
171 GCMChannelStatusRequest::min_poll_interval_seconds()); | 176 GCMChannelStatusRequest::min_poll_interval_seconds()); |
172 if (poll_interval_seconds_ != poll_interval_seconds) { | 177 if (poll_interval_seconds_ != poll_interval_seconds) { |
173 poll_interval_seconds_ = poll_interval_seconds; | 178 poll_interval_seconds_ = poll_interval_seconds; |
174 prefs_->SetInteger(kGCMChannelPollIntervalSeconds, | 179 prefs_->SetInteger(prefs::kGCMChannelPollIntervalSeconds, |
175 poll_interval_seconds_); | 180 poll_interval_seconds_); |
176 } | 181 } |
177 } | 182 } |
178 } | 183 } |
179 | 184 |
180 // Do not schedule next request if syncer is stopped. | 185 // Do not schedule next request if syncer is stopped. |
181 if (started_) | 186 if (started_) |
182 ScheduleRequest(); | 187 ScheduleRequest(); |
183 } | 188 } |
184 | 189 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // Otherwise, add a fuzzing variation to the delay. | 232 // Otherwise, add a fuzzing variation to the delay. |
228 // The fuzzing variation is off when the custom interval is used. | 233 // The fuzzing variation is off when the custom interval is used. |
229 if (!custom_poll_interval_use_count_) | 234 if (!custom_poll_interval_use_count_) |
230 delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds); | 235 delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds); |
231 } | 236 } |
232 | 237 |
233 return base::TimeDelta::FromSeconds(delay_seconds); | 238 return base::TimeDelta::FromSeconds(delay_seconds); |
234 } | 239 } |
235 | 240 |
236 } // namespace gcm | 241 } // namespace gcm |
OLD | NEW |