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#ifndef COMPONENTS_GCM_DRIVER_GCM_CHANNEL_STATUS_SYNCER_H_
6#define COMPONENTS_GCM_DRIVER_GCM_CHANNEL_STATUS_SYNCER_H_
7
8#include "base/compiler_specific.h"
9#include "base/macros.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "base/time/time.h"
14
15class PrefService;
16class PrefRegistrySimple;
17
18namespace net {
19class URLRequestContextGetter;
20}
21
22namespace user_prefs {
23class PrefRegistrySyncable;
24}
25
26namespace gcm {
27
28class GCMChannelStatusRequest;
29class GCMDriver;
30
31// Syncing with the server for GCM channel status that controls if GCM
32// functionality should be enabled or disabled.
33class GCMChannelStatusSyncer {
34 public:
35  static void RegisterPrefs(PrefRegistrySimple* registry);
36  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
37
38  GCMChannelStatusSyncer(
39      GCMDriver* driver,
40      PrefService* prefs,
41      const std::string& channel_status_request_url,
42      const std::string& user_agent,
43      const scoped_refptr<net::URLRequestContextGetter>& request_context);
44  ~GCMChannelStatusSyncer();
45
46  void EnsureStarted();
47  void Stop();
48
49  bool gcm_enabled() const { return gcm_enabled_; }
50
51  // For testing purpose.
52  void set_delay_removed_for_testing(bool delay_removed) {
53    delay_removed_for_testing_ = delay_removed;
54  }
55  base::TimeDelta current_request_delay_interval() const {
56    return current_request_delay_interval_;
57  }
58  static int first_time_delay_seconds();
59
60 private:
61  // Called when a request is completed.
62  void OnRequestCompleted(bool update_received,
63                          bool enabled,
64                          int poll_interval_seconds);
65
66  // Schedules next request to start after appropriate delay.
67  void ScheduleRequest();
68
69  // Creates and starts a request immediately.
70  void StartRequest();
71
72  // Computes and returns a delay with the fuzzing variation added if needed,
73  // after which the request could start.
74  base::TimeDelta GetRequestDelayInterval() const;
75
76  // GCMDriver owns GCMChannelStatusSyncer instance.
77  GCMDriver* driver_;
78  PrefService* prefs_;
79  const std::string channel_status_request_url_;
80  const std::string user_agent_;
81
82  scoped_refptr<net::URLRequestContextGetter> request_context_;
83  scoped_ptr<GCMChannelStatusRequest> request_;
84
85  bool started_;
86  bool gcm_enabled_;
87  int poll_interval_seconds_;
88  base::Time last_check_time_;
89
90  // If non-zero, |poll_interval_seconds_| is overriden by the command line
91  // options for testing purpose. Each time when the custom poll interval is
92  // used, this count is subtracted by one. When it reaches zero, the default
93  // poll interval will be used instead.
94  int custom_poll_interval_use_count_;
95
96  // The flag that indicates if the delay, including fuzzing variation and poll
97  // interval, is removed for testing purpose.
98  bool delay_removed_for_testing_;
99
100  // Tracked for testing purpose.
101  base::TimeDelta current_request_delay_interval_;
102
103  // Used to pass a weak pointer to a task.
104  base::WeakPtrFactory<GCMChannelStatusSyncer> weak_ptr_factory_;
105
106  DISALLOW_COPY_AND_ASSIGN(GCMChannelStatusSyncer);
107};
108
109}  // namespace gcm
110
111#endif  // COMPONENTS_GCM_DRIVER_GCM_CHANNEL_STATUS_SYNCER_H_
112