1// Copyright 2012 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// A simple wrapper around invalidation::InvalidationClient that
6// handles all the startup/shutdown details and hookups.
7
8#ifndef SYNC_NOTIFIER_SYNC_INVALIDATION_LISTENER_H_
9#define SYNC_NOTIFIER_SYNC_INVALIDATION_LISTENER_H_
10
11#include <string>
12
13#include "base/basictypes.h"
14#include "base/callback_forward.h"
15#include "base/compiler_specific.h"
16#include "base/memory/scoped_ptr.h"
17#include "base/memory/weak_ptr.h"
18#include "base/threading/non_thread_safe.h"
19#include "google/cacheinvalidation/include/invalidation-listener.h"
20#include "sync/base/sync_export.h"
21#include "sync/internal_api/public/util/weak_handle.h"
22#include "sync/notifier/ack_handler.h"
23#include "sync/notifier/invalidation_state_tracker.h"
24#include "sync/notifier/invalidator_state.h"
25#include "sync/notifier/push_client_channel.h"
26#include "sync/notifier/state_writer.h"
27#include "sync/notifier/sync_system_resources.h"
28#include "sync/notifier/unacked_invalidation_set.h"
29
30namespace buzz {
31class XmppTaskParentInterface;
32}  // namespace buzz
33
34namespace notifier {
35class PushClient;
36}  // namespace notifier
37
38namespace syncer {
39
40class ObjectIdInvalidationMap;
41class RegistrationManager;
42
43// SyncInvalidationListener is not thread-safe and lives on the sync
44// thread.
45class SYNC_EXPORT_PRIVATE SyncInvalidationListener
46    : public NON_EXPORTED_BASE(invalidation::InvalidationListener),
47      public StateWriter,
48      public SyncNetworkChannel::Observer,
49      public AckHandler,
50      public base::NonThreadSafe {
51 public:
52  typedef base::Callback<invalidation::InvalidationClient*(
53      invalidation::SystemResources*,
54      int,
55      const invalidation::string&,
56      const invalidation::string&,
57      invalidation::InvalidationListener*)> CreateInvalidationClientCallback;
58
59  class SYNC_EXPORT_PRIVATE Delegate {
60   public:
61    virtual ~Delegate();
62
63    virtual void OnInvalidate(
64        const ObjectIdInvalidationMap& invalidations) = 0;
65
66    virtual void OnInvalidatorStateChange(InvalidatorState state) = 0;
67  };
68
69  explicit SyncInvalidationListener(
70      scoped_ptr<notifier::PushClient> push_client);
71
72  // Calls Stop().
73  virtual ~SyncInvalidationListener();
74
75  // Does not take ownership of |delegate| or |state_writer|.
76  // |invalidation_state_tracker| must be initialized.
77  void Start(
78      const CreateInvalidationClientCallback&
79          create_invalidation_client_callback,
80      const std::string& client_id, const std::string& client_info,
81      const std::string& invalidation_bootstrap_data,
82      const UnackedInvalidationsMap& initial_object_states,
83      const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker,
84      Delegate* delegate);
85
86  void UpdateCredentials(const std::string& email, const std::string& token);
87
88  // Update the set of object IDs that we're interested in getting
89  // notifications for.  May be called at any time.
90  void UpdateRegisteredIds(const ObjectIdSet& ids);
91
92  // invalidation::InvalidationListener implementation.
93  virtual void Ready(
94      invalidation::InvalidationClient* client) OVERRIDE;
95  virtual void Invalidate(
96      invalidation::InvalidationClient* client,
97      const invalidation::Invalidation& invalidation,
98      const invalidation::AckHandle& ack_handle) OVERRIDE;
99  virtual void InvalidateUnknownVersion(
100      invalidation::InvalidationClient* client,
101      const invalidation::ObjectId& object_id,
102      const invalidation::AckHandle& ack_handle) OVERRIDE;
103  virtual void InvalidateAll(
104      invalidation::InvalidationClient* client,
105      const invalidation::AckHandle& ack_handle) OVERRIDE;
106  virtual void InformRegistrationStatus(
107      invalidation::InvalidationClient* client,
108      const invalidation::ObjectId& object_id,
109      invalidation::InvalidationListener::RegistrationState reg_state) OVERRIDE;
110  virtual void InformRegistrationFailure(
111      invalidation::InvalidationClient* client,
112      const invalidation::ObjectId& object_id,
113      bool is_transient,
114      const std::string& error_message) OVERRIDE;
115  virtual void ReissueRegistrations(
116      invalidation::InvalidationClient* client,
117      const std::string& prefix,
118      int prefix_length) OVERRIDE;
119  virtual void InformError(
120      invalidation::InvalidationClient* client,
121      const invalidation::ErrorInfo& error_info) OVERRIDE;
122
123  // AckHandler implementation.
124  virtual void Acknowledge(
125      const invalidation::ObjectId& id,
126      const syncer::AckHandle& handle) OVERRIDE;
127  virtual void Drop(
128      const invalidation::ObjectId& id,
129      const syncer::AckHandle& handle) OVERRIDE;
130
131  // StateWriter implementation.
132  virtual void WriteState(const std::string& state) OVERRIDE;
133
134  // SyncNetworkChannel::Observer implementation.
135  virtual void OnNetworkChannelStateChanged(
136      InvalidatorState invalidator_state) OVERRIDE;
137
138  void DoRegistrationUpdate();
139
140  void StopForTest();
141
142 private:
143  void Stop();
144
145  InvalidatorState GetState() const;
146
147  void EmitStateChange();
148
149  // Sends invalidations to their appropriate destination.
150  //
151  // If there are no observers registered for them, they will be saved for
152  // later.
153  //
154  // If there are observers registered, they will be saved (to make sure we
155  // don't drop them until they've been acted on) and emitted to the observers.
156  void DispatchInvalidations(const ObjectIdInvalidationMap& invalidations);
157
158  // Saves invalidations.
159  //
160  // This call isn't synchronous so we can't guarantee these invalidations will
161  // be safely on disk by the end of the call, but it should ensure that the
162  // data makes it to disk eventually.
163  void SaveInvalidations(const ObjectIdInvalidationMap& to_save);
164
165  // Emits previously saved invalidations to their registered observers.
166  void EmitSavedInvalidations(const ObjectIdInvalidationMap& to_emit);
167
168  WeakHandle<AckHandler> GetThisAsAckHandler();
169
170  PushClientChannel push_client_channel_;
171  SyncSystemResources sync_system_resources_;
172  UnackedInvalidationsMap unacked_invalidations_map_;
173  WeakHandle<InvalidationStateTracker> invalidation_state_tracker_;
174  Delegate* delegate_;
175  scoped_ptr<invalidation::InvalidationClient> invalidation_client_;
176  scoped_ptr<RegistrationManager> registration_manager_;
177  // Stored to pass to |registration_manager_| on start.
178  ObjectIdSet registered_ids_;
179
180  // The states of the ticl and the push client.
181  InvalidatorState ticl_state_;
182  InvalidatorState push_client_state_;
183
184  base::WeakPtrFactory<SyncInvalidationListener> weak_ptr_factory_;
185
186  DISALLOW_COPY_AND_ASSIGN(SyncInvalidationListener);
187};
188
189}  // namespace syncer
190
191#endif  // SYNC_NOTIFIER_SYNC_INVALIDATION_LISTENER_H_
192