11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/gcm_driver/gcm_channel_status_syncer.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
81675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#include "base/command_line.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/location.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/prefs/pref_registry_simple.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/prefs/pref_service.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/rand_util.h"
151675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#include "base/strings/string_number_conversions.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/gcm_driver/gcm_channel_status_request.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/gcm_driver/gcm_driver.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pref_registry/pref_registry_syncable.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace gcm {
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The GCM channel's enabled state.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kGCMChannelStatus[] = "gcm.channel_status";
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The GCM channel's polling interval (in seconds).
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval";
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Last time when checking with the GCM channel status server is done.
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kGCMChannelLastCheckTime[] = "gcm.check_time";
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// A small delay to avoid sending request at browser startup time for first-time
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// request.
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kFirstTimeDelaySeconds = 1 * 60;  // 1 minute.
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The fuzzing variation added to the polling delay.
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kGCMChannelRequestTimeJitterSeconds = 15 * 60;  // 15 minues.
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch// The minimum poll interval that can be overridden to.
411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochconst int kMinCustomPollIntervalMinutes = 2;
421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch// Custom poll interval could not be used more than the limit below.
441675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochconst int kMaxNumberToUseCustomPollInterval = 10;
451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochnamespace switches {
491675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
501675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch// Override the default poll interval for testing purpose.
511675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochconst char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval";
521675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
531675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch}  // namepsace switches
541675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterBooleanPref(kGCMChannelStatus, true);
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterIntegerPref(
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kGCMChannelPollIntervalSeconds,
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GCMChannelStatusRequest::default_poll_interval_seconds());
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0);
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::RegisterProfilePrefs(
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    user_prefs::PrefRegistrySyncable* registry) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterBooleanPref(
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kGCMChannelStatus,
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      true,
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterIntegerPref(
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kGCMChannelPollIntervalSeconds,
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GCMChannelStatusRequest::default_poll_interval_seconds(),
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterInt64Pref(
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kGCMChannelLastCheckTime,
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      0,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint GCMChannelStatusSyncer::first_time_delay_seconds() {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return kFirstTimeDelaySeconds;
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGCMChannelStatusSyncer::GCMChannelStatusSyncer(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GCMDriver* driver,
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PrefService* prefs,
891675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    const std::string& channel_status_request_url,
901675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    const std::string& user_agent,
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<net::URLRequestContextGetter>& request_context)
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : driver_(driver),
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prefs_(prefs),
941675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      channel_status_request_url_(channel_status_request_url),
951675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      user_agent_(user_agent),
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_context_(request_context),
971675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      started_(false),
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      gcm_enabled_(true),
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      poll_interval_seconds_(
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          GCMChannelStatusRequest::default_poll_interval_seconds()),
1011675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      custom_poll_interval_use_count_(0),
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      delay_removed_for_testing_(false),
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus);
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (poll_interval_seconds_ <
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GCMChannelStatusRequest::min_poll_interval_seconds()) {
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    poll_interval_seconds_ =
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GCMChannelStatusRequest::min_poll_interval_seconds();
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1111675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(
1121675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          switches::kCustomPollIntervalMinutes)) {
1131675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    std::string value(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
1141675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        switches::kCustomPollIntervalMinutes));
1151675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    int minutes = 0;
1161675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    if (base::StringToInt(value, &minutes)) {
1171675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      DCHECK_GE(minutes, kMinCustomPollIntervalMinutes);
1181675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      if (minutes >= kMinCustomPollIntervalMinutes) {
1191675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        poll_interval_seconds_ = minutes * 60;
1201675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        custom_poll_interval_use_count_ = kMaxNumberToUseCustomPollInterval;
1211675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      }
1221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    }
1231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_check_time_ = base::Time::FromInternalValue(
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prefs_->GetInt64(kGCMChannelLastCheckTime));
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGCMChannelStatusSyncer::~GCMChannelStatusSyncer() {
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::EnsureStarted() {
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Bail out if the request is already scheduled or started.
1331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (started_)
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  started_ = true;
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScheduleRequest();
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::Stop() {
1411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  started_ = false;
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  request_.reset();
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  weak_ptr_factory_.InvalidateWeakPtrs();
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1461675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochvoid GCMChannelStatusSyncer::OnRequestCompleted(bool update_received,
1471675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                                bool enabled,
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                int poll_interval_seconds) {
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(request_);
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  request_.reset();
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Persist the current time as the last request complete time.
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_check_time_ = base::Time::Now();
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefs_->SetInt64(kGCMChannelLastCheckTime,
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   last_check_time_.ToInternalValue());
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1571675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (update_received) {
1581675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    if (gcm_enabled_ != enabled) {
1591675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      gcm_enabled_ = enabled;
1601675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      prefs_->SetBoolean(kGCMChannelStatus, enabled);
1611675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      if (gcm_enabled_)
1621675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        driver_->Enable();
1631675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      else
1641675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        driver_->Disable();
1651675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    }
1661675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
1671675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    // Skip updating poll interval if the custom one is still in effect.
1681675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    if (!custom_poll_interval_use_count_) {
1691675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      DCHECK_GE(poll_interval_seconds,
1701675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                GCMChannelStatusRequest::min_poll_interval_seconds());
1711675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      if (poll_interval_seconds_ != poll_interval_seconds) {
1721675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        poll_interval_seconds_ = poll_interval_seconds;
1731675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        prefs_->SetInteger(kGCMChannelPollIntervalSeconds,
1741675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                           poll_interval_seconds_);
1751675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      }
1761675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    }
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1791675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // Do not schedule next request if syncer is stopped.
1801675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (started_)
1811675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    ScheduleRequest();
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::ScheduleRequest() {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  current_request_delay_interval_ = GetRequestDelayInterval();
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MessageLoop::current()->PostDelayedTask(
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&GCMChannelStatusSyncer::StartRequest,
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_ptr_factory_.GetWeakPtr()),
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      current_request_delay_interval_);
1911675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
1921675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (custom_poll_interval_use_count_)
1931675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    custom_poll_interval_use_count_--;
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMChannelStatusSyncer::StartRequest() {
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!request_);
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  request_.reset(new GCMChannelStatusRequest(
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_context_,
2011675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      channel_status_request_url_,
2021675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      user_agent_,
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&GCMChannelStatusSyncer::OnRequestCompleted,
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_ptr_factory_.GetWeakPtr())));
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  request_->Start();
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta GCMChannelStatusSyncer::GetRequestDelayInterval() const {
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // No delay during testing.
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (delay_removed_for_testing_)
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return base::TimeDelta();
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make sure that checking with server occurs at polling interval, regardless
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // whether the browser restarts.
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int64 delay_seconds = poll_interval_seconds_ -
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      (base::Time::Now() - last_check_time_).InSeconds();
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (delay_seconds < 0)
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    delay_seconds = 0;
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (last_check_time_.is_null()) {
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // For the first-time request, add a small delay to avoid sending request at
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // browser startup time.
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!delay_seconds);
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    delay_seconds = kFirstTimeDelaySeconds;
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Otherwise, add a fuzzing variation to the delay.
2271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    // The fuzzing variation is off when the custom interval is used.
2281675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    if (!custom_poll_interval_use_count_)
2291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds);
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::TimeDelta::FromSeconds(delay_seconds);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace gcm
236