Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: components/gcm_driver/gcm_channel_status_syncer.cc

Issue 561943002: Reland: Add GCMChannelStatusSyncer to schedule requests and enable/disable GCM (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix try jobs Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/gcm_driver/gcm_channel_status_syncer.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/rand_util.h"
14 #include "components/gcm_driver/gcm_channel_status_request.h"
15 #include "components/gcm_driver/gcm_driver.h"
16
17 namespace gcm {
18
19 namespace {
20
21 // The GCM channel's enabled state.
22 const char kGCMChannelStatus[] = "gcm.channel_status";
23
24 // The GCM channel's polling interval (in seconds).
25 const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval";
26
27 // Last time when checking with the GCM channel status server is done.
28 const char kGCMChannelLastCheckTime[] = "gcm.check_time";
29
30 // A small delay to avoid sending request at browser startup time for first-time
31 // request.
32 const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute.
33
34 // The fuzzing variation added to the polling delay.
35 const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues.
36
37 } // namespace
38
39 // static
40 void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) {
41 registry->RegisterBooleanPref(kGCMChannelStatus, true);
42 registry->RegisterIntegerPref(
43 kGCMChannelPollIntervalSeconds,
44 GCMChannelStatusRequest::default_poll_interval_seconds());
45 registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0);
46 }
47
48 // static
49 void GCMChannelStatusSyncer::RegisterProfilePrefs(
50 user_prefs::PrefRegistrySyncable* registry) {
51 registry->RegisterBooleanPref(
52 kGCMChannelStatus,
53 true,
54 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
55 registry->RegisterIntegerPref(
56 kGCMChannelPollIntervalSeconds,
57 GCMChannelStatusRequest::default_poll_interval_seconds(),
58 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
59 registry->RegisterInt64Pref(
60 kGCMChannelLastCheckTime,
61 0,
62 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
63 }
64
65 // static
66 int GCMChannelStatusSyncer::first_time_delay_seconds() {
67 return kFirstTimeDelaySeconds;
68 }
69
70 GCMChannelStatusSyncer::GCMChannelStatusSyncer(
71 GCMDriver* driver,
72 PrefService* prefs,
73 scoped_refptr<net::URLRequestContextGetter> request_context)
74 : driver_(driver),
75 prefs_(prefs),
76 request_context_(request_context),
77 gcm_enabled_(true),
78 poll_interval_seconds_(
79 GCMChannelStatusRequest::default_poll_interval_seconds()),
80 delay_removed_for_testing_(false),
81 weak_ptr_factory_(this) {
82 gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus);
83 poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds);
84 if (poll_interval_seconds_ <
85 GCMChannelStatusRequest::min_poll_interval_seconds()) {
86 poll_interval_seconds_ =
87 GCMChannelStatusRequest::min_poll_interval_seconds();
88 }
89 last_check_time_ = base::Time::FromInternalValue(
90 prefs_->GetInt64(kGCMChannelLastCheckTime));
91 }
92
93 GCMChannelStatusSyncer::~GCMChannelStatusSyncer() {
94 }
95
96 void GCMChannelStatusSyncer::EnsureStarted() {
97 // Bail out if already started.
98 if (request_)
99 return;
100
101 ScheduleRequest();
102 }
103
104 void GCMChannelStatusSyncer::Stop() {
105 request_.reset();
106 weak_ptr_factory_.InvalidateWeakPtrs();
107 }
108
109 void GCMChannelStatusSyncer::OnRequestCompleted(bool enabled,
110 int poll_interval_seconds) {
111 DCHECK(request_);
112 request_.reset();
113
114 // Persist the current time as the last request complete time.
115 last_check_time_ = base::Time::Now();
fgorski 2014/09/11 18:24:35 injected clock is typically more useful for testin
jianli 2014/09/11 21:04:30 Agreed. For now, testing with real clock seems to
116 prefs_->SetInt64(kGCMChannelLastCheckTime,
117 last_check_time_.ToInternalValue());
118
119 if (gcm_enabled_ != enabled) {
120 gcm_enabled_ = enabled;
121 prefs_->SetBoolean(kGCMChannelStatus, enabled);
122 if (gcm_enabled_)
123 driver_->Enable();
124 else
125 driver_->Disable();
126 }
127
128 if (poll_interval_seconds_ != poll_interval_seconds) {
129 poll_interval_seconds_ = poll_interval_seconds;
fgorski 2014/09/11 18:24:35 this code should check for min poll interval. try
jianli 2014/09/11 21:04:30 OnRequestCompleted is called with min value enforc
130 prefs_->SetInteger(kGCMChannelPollIntervalSeconds, poll_interval_seconds_);
131 }
132
133 ScheduleRequest();
134 }
135
136 void GCMChannelStatusSyncer::ScheduleRequest() {
137 current_request_delay_interval_ = GetRequestDelayInterval();
138 base::MessageLoop::current()->PostDelayedTask(
139 FROM_HERE,
140 base::Bind(&GCMChannelStatusSyncer::StartRequest,
141 weak_ptr_factory_.GetWeakPtr()),
142 current_request_delay_interval_);
143 }
144
145 void GCMChannelStatusSyncer::StartRequest() {
146 DCHECK(!request_);
147
148 request_.reset(new GCMChannelStatusRequest(
149 request_context_,
150 base::Bind(&GCMChannelStatusSyncer::OnRequestCompleted,
151 weak_ptr_factory_.GetWeakPtr())));
152 request_->Start();
153 }
154
155 base::TimeDelta GCMChannelStatusSyncer::GetRequestDelayInterval() const {
156 // No delay during testing.
157 if (delay_removed_for_testing_)
158 return base::TimeDelta();
159
160 // Make sure that checking with server occurs at polling interval, regardless
161 // whether the browser restarts.
162 int delay_seconds = static_cast<int>(poll_interval_seconds_ -
163 (base::Time::Now() - last_check_time_).InSeconds());
164 if (delay_seconds < 0)
165 delay_seconds = 0;
166
167 if (last_check_time_.is_null()) {
168 // For the first-time request, add a small delay to avoid sending request at
169 // browser startup time.
170 DCHECK(!delay_seconds);
171 delay_seconds = kFirstTimeDelaySeconds;
172 } else {
173 // Otherwise, add a fuzzing variation to the delay.
174 delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds);
175 }
176
177 return base::TimeDelta::FromSeconds(delay_seconds);
178 }
179
180 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698