• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 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 #include "sync/notifier/non_blocking_invalidator.h"
6 
7 #include <cstddef>
8 
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/thread.h"
15 #include "jingle/notifier/listener/push_client.h"
16 #include "sync/notifier/invalidation_notifier.h"
17 #include "sync/notifier/object_id_invalidation_map.h"
18 
19 namespace syncer {
20 
21 class NonBlockingInvalidator::Core
22     : public base::RefCountedThreadSafe<NonBlockingInvalidator::Core>,
23       // InvalidationHandler to observe the InvalidationNotifier we create.
24       public InvalidationHandler {
25  public:
26   // Called on parent thread.  |delegate_observer| should be
27   // initialized.
28   explicit Core(
29       const WeakHandle<InvalidationHandler>& delegate_observer);
30 
31   // Helpers called on I/O thread.
32   void Initialize(
33       const notifier::NotifierOptions& notifier_options,
34       const std::string& invalidator_client_id,
35       const UnackedInvalidationsMap& saved_invalidations,
36       const std::string& invalidation_bootstrap_data,
37       const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker,
38       const std::string& client_info);
39   void Teardown();
40   void UpdateRegisteredIds(const ObjectIdSet& ids);
41   void UpdateCredentials(const std::string& email, const std::string& token);
42 
43   // InvalidationHandler implementation (all called on I/O thread by
44   // InvalidationNotifier).
45   virtual void OnInvalidatorStateChange(InvalidatorState reason) OVERRIDE;
46   virtual void OnIncomingInvalidation(
47       const ObjectIdInvalidationMap& invalidation_map) OVERRIDE;
48 
49  private:
50   friend class
51       base::RefCountedThreadSafe<NonBlockingInvalidator::Core>;
52   // Called on parent or I/O thread.
53   virtual ~Core();
54 
55   // The variables below should be used only on the I/O thread.
56   const WeakHandle<InvalidationHandler> delegate_observer_;
57   scoped_ptr<InvalidationNotifier> invalidation_notifier_;
58   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
59 
60   DISALLOW_COPY_AND_ASSIGN(Core);
61 };
62 
Core(const WeakHandle<InvalidationHandler> & delegate_observer)63 NonBlockingInvalidator::Core::Core(
64     const WeakHandle<InvalidationHandler>& delegate_observer)
65     : delegate_observer_(delegate_observer) {
66   DCHECK(delegate_observer_.IsInitialized());
67 }
68 
~Core()69 NonBlockingInvalidator::Core::~Core() {
70 }
71 
Initialize(const notifier::NotifierOptions & notifier_options,const std::string & invalidator_client_id,const UnackedInvalidationsMap & saved_invalidations,const std::string & invalidation_bootstrap_data,const WeakHandle<InvalidationStateTracker> & invalidation_state_tracker,const std::string & client_info)72 void NonBlockingInvalidator::Core::Initialize(
73     const notifier::NotifierOptions& notifier_options,
74     const std::string& invalidator_client_id,
75     const UnackedInvalidationsMap& saved_invalidations,
76     const std::string& invalidation_bootstrap_data,
77     const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker,
78     const std::string& client_info) {
79   DCHECK(notifier_options.request_context_getter.get());
80   DCHECK_EQ(notifier::NOTIFICATION_SERVER,
81             notifier_options.notification_method);
82   network_task_runner_ = notifier_options.request_context_getter->
83       GetNetworkTaskRunner();
84   DCHECK(network_task_runner_->BelongsToCurrentThread());
85   invalidation_notifier_.reset(
86       new InvalidationNotifier(
87           notifier::PushClient::CreateDefaultOnIOThread(notifier_options),
88           invalidator_client_id,
89           saved_invalidations,
90           invalidation_bootstrap_data,
91           invalidation_state_tracker,
92           client_info));
93   invalidation_notifier_->RegisterHandler(this);
94 }
95 
Teardown()96 void NonBlockingInvalidator::Core::Teardown() {
97   DCHECK(network_task_runner_->BelongsToCurrentThread());
98   invalidation_notifier_->UnregisterHandler(this);
99   invalidation_notifier_.reset();
100   network_task_runner_ = NULL;
101 }
102 
UpdateRegisteredIds(const ObjectIdSet & ids)103 void NonBlockingInvalidator::Core::UpdateRegisteredIds(const ObjectIdSet& ids) {
104   DCHECK(network_task_runner_->BelongsToCurrentThread());
105   invalidation_notifier_->UpdateRegisteredIds(this, ids);
106 }
107 
UpdateCredentials(const std::string & email,const std::string & token)108 void NonBlockingInvalidator::Core::UpdateCredentials(const std::string& email,
109                                                      const std::string& token) {
110   DCHECK(network_task_runner_->BelongsToCurrentThread());
111   invalidation_notifier_->UpdateCredentials(email, token);
112 }
113 
OnInvalidatorStateChange(InvalidatorState reason)114 void NonBlockingInvalidator::Core::OnInvalidatorStateChange(
115     InvalidatorState reason) {
116   DCHECK(network_task_runner_->BelongsToCurrentThread());
117   delegate_observer_.Call(
118       FROM_HERE, &InvalidationHandler::OnInvalidatorStateChange, reason);
119 }
120 
OnIncomingInvalidation(const ObjectIdInvalidationMap & invalidation_map)121 void NonBlockingInvalidator::Core::OnIncomingInvalidation(
122     const ObjectIdInvalidationMap& invalidation_map) {
123   DCHECK(network_task_runner_->BelongsToCurrentThread());
124   delegate_observer_.Call(FROM_HERE,
125                           &InvalidationHandler::OnIncomingInvalidation,
126                           invalidation_map);
127 }
128 
NonBlockingInvalidator(const notifier::NotifierOptions & notifier_options,const std::string & invalidator_client_id,const UnackedInvalidationsMap & saved_invalidations,const std::string & invalidation_bootstrap_data,const WeakHandle<InvalidationStateTracker> & invalidation_state_tracker,const std::string & client_info)129 NonBlockingInvalidator::NonBlockingInvalidator(
130     const notifier::NotifierOptions& notifier_options,
131     const std::string& invalidator_client_id,
132     const UnackedInvalidationsMap& saved_invalidations,
133     const std::string& invalidation_bootstrap_data,
134     const WeakHandle<InvalidationStateTracker>&
135         invalidation_state_tracker,
136     const std::string& client_info)
137     : parent_task_runner_(base::ThreadTaskRunnerHandle::Get()),
138       network_task_runner_(
139           notifier_options.request_context_getter->GetNetworkTaskRunner()),
140       weak_ptr_factory_(this) {
141   core_ = new Core(MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()));
142 
143   if (!network_task_runner_->PostTask(
144           FROM_HERE,
145           base::Bind(
146               &NonBlockingInvalidator::Core::Initialize,
147               core_.get(),
148               notifier_options,
149               invalidator_client_id,
150               saved_invalidations,
151               invalidation_bootstrap_data,
152               invalidation_state_tracker,
153               client_info))) {
154     NOTREACHED();
155   }
156 }
157 
~NonBlockingInvalidator()158 NonBlockingInvalidator::~NonBlockingInvalidator() {
159   DCHECK(parent_task_runner_->BelongsToCurrentThread());
160   if (!network_task_runner_->PostTask(
161           FROM_HERE,
162           base::Bind(&NonBlockingInvalidator::Core::Teardown,
163                      core_.get()))) {
164     DVLOG(1) << "Network thread stopped before invalidator is destroyed.";
165   }
166 }
167 
RegisterHandler(InvalidationHandler * handler)168 void NonBlockingInvalidator::RegisterHandler(InvalidationHandler* handler) {
169   DCHECK(parent_task_runner_->BelongsToCurrentThread());
170   registrar_.RegisterHandler(handler);
171 }
172 
UpdateRegisteredIds(InvalidationHandler * handler,const ObjectIdSet & ids)173 void NonBlockingInvalidator::UpdateRegisteredIds(InvalidationHandler* handler,
174                                                  const ObjectIdSet& ids) {
175   DCHECK(parent_task_runner_->BelongsToCurrentThread());
176   registrar_.UpdateRegisteredIds(handler, ids);
177   if (!network_task_runner_->PostTask(
178           FROM_HERE,
179           base::Bind(
180               &NonBlockingInvalidator::Core::UpdateRegisteredIds,
181               core_.get(),
182               registrar_.GetAllRegisteredIds()))) {
183     NOTREACHED();
184   }
185 }
186 
UnregisterHandler(InvalidationHandler * handler)187 void NonBlockingInvalidator::UnregisterHandler(InvalidationHandler* handler) {
188   DCHECK(parent_task_runner_->BelongsToCurrentThread());
189   registrar_.UnregisterHandler(handler);
190 }
191 
GetInvalidatorState() const192 InvalidatorState NonBlockingInvalidator::GetInvalidatorState() const {
193   DCHECK(parent_task_runner_->BelongsToCurrentThread());
194   return registrar_.GetInvalidatorState();
195 }
196 
UpdateCredentials(const std::string & email,const std::string & token)197 void NonBlockingInvalidator::UpdateCredentials(const std::string& email,
198                                                const std::string& token) {
199   DCHECK(parent_task_runner_->BelongsToCurrentThread());
200   if (!network_task_runner_->PostTask(
201           FROM_HERE,
202           base::Bind(&NonBlockingInvalidator::Core::UpdateCredentials,
203                      core_.get(), email, token))) {
204     NOTREACHED();
205   }
206 }
207 
OnInvalidatorStateChange(InvalidatorState state)208 void NonBlockingInvalidator::OnInvalidatorStateChange(InvalidatorState state) {
209   DCHECK(parent_task_runner_->BelongsToCurrentThread());
210   registrar_.UpdateInvalidatorState(state);
211 }
212 
OnIncomingInvalidation(const ObjectIdInvalidationMap & invalidation_map)213 void NonBlockingInvalidator::OnIncomingInvalidation(
214         const ObjectIdInvalidationMap& invalidation_map) {
215   DCHECK(parent_task_runner_->BelongsToCurrentThread());
216   registrar_.DispatchInvalidationsToHandlers(invalidation_map);
217 }
218 
219 }  // namespace syncer
220