blob: 1d520b857ab80e9f527ff15ad52cdc63f8597d73 [file] [log] [blame]
[email protected]24c9ee52014-06-02 22:17:501// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]0a80fed2011-03-24 22:31:482// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]44828772014-06-06 02:56:525#include "components/invalidation/non_blocking_invalidator.h"
[email protected]0a80fed2011-03-24 22:31:486
[email protected]85b25eb2012-08-10 19:32:087#include <cstddef>
8
[email protected]4969b0122012-06-16 01:58:289#include "base/location.h"
[email protected]0a80fed2011-03-24 22:31:4810#include "base/logging.h"
[email protected]942e2022011-04-07 22:27:4311#include "base/memory/scoped_ptr.h"
[email protected]4969b0122012-06-16 01:58:2812#include "base/single_thread_task_runner.h"
13#include "base/thread_task_runner_handle.h"
[email protected]942e2022011-04-07 22:27:4314#include "base/threading/thread.h"
[email protected]44828772014-06-06 02:56:5215#include "components/invalidation/gcm_network_channel_delegate.h"
[email protected]001bbfdc2014-07-17 19:28:4616#include "components/invalidation/invalidation_handler.h"
[email protected]44828772014-06-06 02:56:5217#include "components/invalidation/invalidation_notifier.h"
[email protected]001bbfdc2014-07-17 19:28:4618#include "components/invalidation/object_id_invalidation_map.h"
[email protected]44828772014-06-06 02:56:5219#include "components/invalidation/sync_system_resources.h"
[email protected]1f7eba72012-05-30 09:10:1720#include "jingle/notifier/listener/push_client.h"
[email protected]0a80fed2011-03-24 22:31:4821
[email protected]65f173552012-06-28 22:43:5822namespace syncer {
[email protected]0a80fed2011-03-24 22:31:4823
[email protected]04a830a2014-01-04 02:48:5124struct NonBlockingInvalidator::InitializeOptions {
25 InitializeOptions(
26 NetworkChannelCreator network_channel_creator,
27 const std::string& invalidator_client_id,
28 const UnackedInvalidationsMap& saved_invalidations,
29 const std::string& invalidation_bootstrap_data,
[email protected]5fe215c2014-08-09 06:04:2830 const base::WeakPtr<InvalidationStateTracker>& invalidation_state_tracker,
31 const scoped_refptr<base::SingleThreadTaskRunner>&
32 invalidation_state_tracker_task_runner,
[email protected]04a830a2014-01-04 02:48:5133 const std::string& client_info,
34 scoped_refptr<net::URLRequestContextGetter> request_context_getter)
35 : network_channel_creator(network_channel_creator),
36 invalidator_client_id(invalidator_client_id),
37 saved_invalidations(saved_invalidations),
38 invalidation_bootstrap_data(invalidation_bootstrap_data),
39 invalidation_state_tracker(invalidation_state_tracker),
[email protected]5fe215c2014-08-09 06:04:2840 invalidation_state_tracker_task_runner(
41 invalidation_state_tracker_task_runner),
[email protected]04a830a2014-01-04 02:48:5142 client_info(client_info),
[email protected]5fe215c2014-08-09 06:04:2843 request_context_getter(request_context_getter) {}
[email protected]04a830a2014-01-04 02:48:5144
45 NetworkChannelCreator network_channel_creator;
46 std::string invalidator_client_id;
47 UnackedInvalidationsMap saved_invalidations;
48 std::string invalidation_bootstrap_data;
[email protected]5fe215c2014-08-09 06:04:2849 base::WeakPtr<InvalidationStateTracker> invalidation_state_tracker;
50 scoped_refptr<base::SingleThreadTaskRunner>
51 invalidation_state_tracker_task_runner;
[email protected]04a830a2014-01-04 02:48:5152 std::string client_info;
53 scoped_refptr<net::URLRequestContextGetter> request_context_getter;
54};
55
[email protected]5cb5b182014-03-18 00:32:3956namespace {
57// This class provides a wrapper for a logging class in order to receive
58// callbacks across threads, without having to worry about owner threads.
59class CallbackProxy {
60 public:
61 explicit CallbackProxy(
62 base::Callback<void(const base::DictionaryValue&)> callback);
63 ~CallbackProxy();
64
65 void Run(const base::DictionaryValue& value);
66
67 private:
68 static void DoRun(base::Callback<void(const base::DictionaryValue&)> callback,
69 scoped_ptr<base::DictionaryValue> value);
70
71 base::Callback<void(const base::DictionaryValue&)> callback_;
72 scoped_refptr<base::SingleThreadTaskRunner> running_thread_;
73
74 DISALLOW_COPY_AND_ASSIGN(CallbackProxy);
75};
76
77CallbackProxy::CallbackProxy(
78 base::Callback<void(const base::DictionaryValue&)> callback)
79 : callback_(callback),
80 running_thread_(base::ThreadTaskRunnerHandle::Get()) {}
81
82CallbackProxy::~CallbackProxy() {}
83
84void CallbackProxy::DoRun(
85 base::Callback<void(const base::DictionaryValue&)> callback,
86 scoped_ptr<base::DictionaryValue> value) {
87 callback.Run(*value);
88}
89
90void CallbackProxy::Run(const base::DictionaryValue& value) {
91 scoped_ptr<base::DictionaryValue> copied(value.DeepCopy());
92 running_thread_->PostTask(
93 FROM_HERE,
94 base::Bind(&CallbackProxy::DoRun, callback_, base::Passed(&copied)));
95}
96}
[email protected]04a830a2014-01-04 02:48:5197
[email protected]a329cb82012-08-28 03:17:5898class NonBlockingInvalidator::Core
99 : public base::RefCountedThreadSafe<NonBlockingInvalidator::Core>,
100 // InvalidationHandler to observe the InvalidationNotifier we create.
101 public InvalidationHandler {
[email protected]942e2022011-04-07 22:27:43102 public:
[email protected]3ee8ec72014-04-16 21:38:50103 // Called on parent thread. |delegate_observer| should be initialized.
[email protected]5fe215c2014-08-09 06:04:28104 Core(const base::WeakPtr<NonBlockingInvalidator>& delegate_observer,
105 const scoped_refptr<base::SingleThreadTaskRunner>&
106 delegate_observer_task_runner);
[email protected]942e2022011-04-07 22:27:43107
108 // Helpers called on I/O thread.
[email protected]e3b0ee52011-10-12 03:04:13109 void Initialize(
[email protected]04a830a2014-01-04 02:48:51110 const NonBlockingInvalidator::InitializeOptions& initialize_options);
[email protected]942e2022011-04-07 22:27:43111 void Teardown();
[email protected]d914f022012-07-27 02:02:00112 void UpdateRegisteredIds(const ObjectIdSet& ids);
[email protected]942e2022011-04-07 22:27:43113 void UpdateCredentials(const std::string& email, const std::string& token);
[email protected]5cb5b182014-03-18 00:32:39114 void RequestDetailedStatus(
[email protected]40848a92014-03-24 22:41:02115 base::Callback<void(const base::DictionaryValue&)> callback) const;
[email protected]942e2022011-04-07 22:27:43116
[email protected]a329cb82012-08-28 03:17:58117 // InvalidationHandler implementation (all called on I/O thread by
[email protected]7800d792012-05-30 02:34:48118 // InvalidationNotifier).
dcheng00ea022b2014-10-21 11:24:56119 void OnInvalidatorStateChange(InvalidatorState reason) override;
120 void OnIncomingInvalidation(
mostynbfe59f482014-10-06 15:04:46121 const ObjectIdInvalidationMap& invalidation_map) override;
dcheng00ea022b2014-10-21 11:24:56122 std::string GetOwnerName() const override;
[email protected]942e2022011-04-07 22:27:43123
124 private:
125 friend class
[email protected]a329cb82012-08-28 03:17:58126 base::RefCountedThreadSafe<NonBlockingInvalidator::Core>;
[email protected]942e2022011-04-07 22:27:43127 // Called on parent or I/O thread.
dcheng00ea022b2014-10-21 11:24:56128 ~Core() override;
[email protected]942e2022011-04-07 22:27:43129
[email protected]b9908a242011-11-19 09:31:32130 // The variables below should be used only on the I/O thread.
[email protected]5fe215c2014-08-09 06:04:28131 const base::WeakPtr<NonBlockingInvalidator> delegate_observer_;
132 scoped_refptr<base::SingleThreadTaskRunner> delegate_observer_task_runner_;
[email protected]942e2022011-04-07 22:27:43133 scoped_ptr<InvalidationNotifier> invalidation_notifier_;
[email protected]4969b0122012-06-16 01:58:28134 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
[email protected]b9908a242011-11-19 09:31:32135
[email protected]942e2022011-04-07 22:27:43136 DISALLOW_COPY_AND_ASSIGN(Core);
137};
138
[email protected]a329cb82012-08-28 03:17:58139NonBlockingInvalidator::Core::Core(
[email protected]5fe215c2014-08-09 06:04:28140 const base::WeakPtr<NonBlockingInvalidator>& delegate_observer,
141 const scoped_refptr<base::SingleThreadTaskRunner>&
142 delegate_observer_task_runner)
143 : delegate_observer_(delegate_observer),
144 delegate_observer_task_runner_(delegate_observer_task_runner) {
145 DCHECK(delegate_observer_);
dchengf0fe8bf2014-08-27 18:32:36146 DCHECK(delegate_observer_task_runner_.get());
[email protected]942e2022011-04-07 22:27:43147}
148
[email protected]a329cb82012-08-28 03:17:58149NonBlockingInvalidator::Core::~Core() {
[email protected]942e2022011-04-07 22:27:43150}
151
[email protected]a329cb82012-08-28 03:17:58152void NonBlockingInvalidator::Core::Initialize(
[email protected]04a830a2014-01-04 02:48:51153 const NonBlockingInvalidator::InitializeOptions& initialize_options) {
154 DCHECK(initialize_options.request_context_getter.get());
155 network_task_runner_ =
156 initialize_options.request_context_getter->GetNetworkTaskRunner();
[email protected]4969b0122012-06-16 01:58:28157 DCHECK(network_task_runner_->BelongsToCurrentThread());
[email protected]04a830a2014-01-04 02:48:51158 scoped_ptr<SyncNetworkChannel> network_channel =
159 initialize_options.network_channel_creator.Run();
[email protected]5fe215c2014-08-09 06:04:28160 invalidation_notifier_.reset(new InvalidationNotifier(
161 network_channel.Pass(),
162 initialize_options.invalidator_client_id,
163 initialize_options.saved_invalidations,
164 initialize_options.invalidation_bootstrap_data,
165 initialize_options.invalidation_state_tracker,
166 initialize_options.invalidation_state_tracker_task_runner,
167 initialize_options.client_info));
[email protected]85b25eb2012-08-10 19:32:08168 invalidation_notifier_->RegisterHandler(this);
[email protected]942e2022011-04-07 22:27:43169}
170
[email protected]a329cb82012-08-28 03:17:58171void NonBlockingInvalidator::Core::Teardown() {
[email protected]4969b0122012-06-16 01:58:28172 DCHECK(network_task_runner_->BelongsToCurrentThread());
[email protected]85b25eb2012-08-10 19:32:08173 invalidation_notifier_->UnregisterHandler(this);
[email protected]942e2022011-04-07 22:27:43174 invalidation_notifier_.reset();
[email protected]4969b0122012-06-16 01:58:28175 network_task_runner_ = NULL;
[email protected]942e2022011-04-07 22:27:43176}
177
[email protected]a329cb82012-08-28 03:17:58178void NonBlockingInvalidator::Core::UpdateRegisteredIds(const ObjectIdSet& ids) {
[email protected]d914f022012-07-27 02:02:00179 DCHECK(network_task_runner_->BelongsToCurrentThread());
180 invalidation_notifier_->UpdateRegisteredIds(this, ids);
181}
182
[email protected]a329cb82012-08-28 03:17:58183void NonBlockingInvalidator::Core::UpdateCredentials(const std::string& email,
184 const std::string& token) {
[email protected]4969b0122012-06-16 01:58:28185 DCHECK(network_task_runner_->BelongsToCurrentThread());
[email protected]942e2022011-04-07 22:27:43186 invalidation_notifier_->UpdateCredentials(email, token);
187}
188
[email protected]5cb5b182014-03-18 00:32:39189void NonBlockingInvalidator::Core::RequestDetailedStatus(
[email protected]40848a92014-03-24 22:41:02190 base::Callback<void(const base::DictionaryValue&)> callback) const {
[email protected]5cb5b182014-03-18 00:32:39191 DCHECK(network_task_runner_->BelongsToCurrentThread());
192 invalidation_notifier_->RequestDetailedStatus(callback);
193}
194
[email protected]08a6f9992012-09-07 19:19:16195void NonBlockingInvalidator::Core::OnInvalidatorStateChange(
196 InvalidatorState reason) {
[email protected]2d3d1d12012-06-18 20:50:28197 DCHECK(network_task_runner_->BelongsToCurrentThread());
[email protected]5fe215c2014-08-09 06:04:28198 delegate_observer_task_runner_->PostTask(
199 FROM_HERE,
200 base::Bind(&NonBlockingInvalidator::OnInvalidatorStateChange,
201 delegate_observer_,
202 reason));
[email protected]2d3d1d12012-06-18 20:50:28203}
204
[email protected]08a6f9992012-09-07 19:19:16205void NonBlockingInvalidator::Core::OnIncomingInvalidation(
[email protected]0d0b59d2013-02-02 00:24:47206 const ObjectIdInvalidationMap& invalidation_map) {
[email protected]4969b0122012-06-16 01:58:28207 DCHECK(network_task_runner_->BelongsToCurrentThread());
[email protected]5fe215c2014-08-09 06:04:28208 delegate_observer_task_runner_->PostTask(
209 FROM_HERE,
210 base::Bind(&NonBlockingInvalidator::OnIncomingInvalidation,
211 delegate_observer_,
212 invalidation_map));
[email protected]942e2022011-04-07 22:27:43213}
214
[email protected]9b0d66b2014-02-20 13:16:01215std::string NonBlockingInvalidator::Core::GetOwnerName() const {
216 return "Sync";
217}
218
[email protected]a329cb82012-08-28 03:17:58219NonBlockingInvalidator::NonBlockingInvalidator(
[email protected]04a830a2014-01-04 02:48:51220 NetworkChannelCreator network_channel_creator,
[email protected]d5511232013-03-28 01:34:54221 const std::string& invalidator_client_id,
[email protected]a7b16392013-11-26 22:46:26222 const UnackedInvalidationsMap& saved_invalidations,
[email protected]8cdb6892012-10-03 05:54:40223 const std::string& invalidation_bootstrap_data,
[email protected]3ee8ec72014-04-16 21:38:50224 InvalidationStateTracker* invalidation_state_tracker,
[email protected]04a830a2014-01-04 02:48:51225 const std::string& client_info,
226 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter)
[email protected]3ee8ec72014-04-16 21:38:50227 : invalidation_state_tracker_(invalidation_state_tracker),
228 parent_task_runner_(base::ThreadTaskRunnerHandle::Get()),
[email protected]04a830a2014-01-04 02:48:51229 network_task_runner_(request_context_getter->GetNetworkTaskRunner()),
[email protected]37d5b3472013-10-10 16:20:36230 weak_ptr_factory_(this) {
[email protected]5fe215c2014-08-09 06:04:28231 base::WeakPtr<NonBlockingInvalidator> weak_ptr_this =
232 weak_ptr_factory_.GetWeakPtr();
233 weak_ptr_this.get(); // Bind to this thread.
[email protected]37d5b3472013-10-10 16:20:36234
[email protected]5fe215c2014-08-09 06:04:28235 core_ = new Core(weak_ptr_this,
236 base::MessageLoopProxy::current());
237
238 InitializeOptions initialize_options(network_channel_creator,
239 invalidator_client_id,
240 saved_invalidations,
241 invalidation_bootstrap_data,
242 weak_ptr_this,
243 base::MessageLoopProxy::current(),
244 client_info,
245 request_context_getter);
[email protected]04a830a2014-01-04 02:48:51246
[email protected]4969b0122012-06-16 01:58:28247 if (!network_task_runner_->PostTask(
[email protected]daf4e102011-04-26 08:30:28248 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02249 base::Bind(
[email protected]a329cb82012-08-28 03:17:58250 &NonBlockingInvalidator::Core::Initialize,
[email protected]09e170f2011-10-28 23:22:02251 core_.get(),
[email protected]04a830a2014-01-04 02:48:51252 initialize_options))) {
[email protected]daf4e102011-04-26 08:30:28253 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18254 }
[email protected]0a80fed2011-03-24 22:31:48255}
256
[email protected]a329cb82012-08-28 03:17:58257NonBlockingInvalidator::~NonBlockingInvalidator() {
[email protected]4969b0122012-06-16 01:58:28258 DCHECK(parent_task_runner_->BelongsToCurrentThread());
259 if (!network_task_runner_->PostTask(
[email protected]daf4e102011-04-26 08:30:28260 FROM_HERE,
[email protected]a329cb82012-08-28 03:17:58261 base::Bind(&NonBlockingInvalidator::Core::Teardown,
[email protected]09e170f2011-10-28 23:22:02262 core_.get()))) {
[email protected]93dcabfb2013-07-31 01:31:55263 DVLOG(1) << "Network thread stopped before invalidator is destroyed.";
[email protected]0a5612052011-06-29 03:29:18264 }
[email protected]0a80fed2011-03-24 22:31:48265}
266
[email protected]a329cb82012-08-28 03:17:58267void NonBlockingInvalidator::RegisterHandler(InvalidationHandler* handler) {
[email protected]65293822012-08-10 04:07:19268 DCHECK(parent_task_runner_->BelongsToCurrentThread());
[email protected]85b25eb2012-08-10 19:32:08269 registrar_.RegisterHandler(handler);
270}
271
[email protected]a329cb82012-08-28 03:17:58272void NonBlockingInvalidator::UpdateRegisteredIds(InvalidationHandler* handler,
273 const ObjectIdSet& ids) {
[email protected]85b25eb2012-08-10 19:32:08274 DCHECK(parent_task_runner_->BelongsToCurrentThread());
275 registrar_.UpdateRegisteredIds(handler, ids);
[email protected]d914f022012-07-27 02:02:00276 if (!network_task_runner_->PostTask(
277 FROM_HERE,
278 base::Bind(
[email protected]a329cb82012-08-28 03:17:58279 &NonBlockingInvalidator::Core::UpdateRegisteredIds,
[email protected]d914f022012-07-27 02:02:00280 core_.get(),
[email protected]85b25eb2012-08-10 19:32:08281 registrar_.GetAllRegisteredIds()))) {
[email protected]d914f022012-07-27 02:02:00282 NOTREACHED();
283 }
[email protected]0a80fed2011-03-24 22:31:48284}
285
[email protected]a329cb82012-08-28 03:17:58286void NonBlockingInvalidator::UnregisterHandler(InvalidationHandler* handler) {
[email protected]85b25eb2012-08-10 19:32:08287 DCHECK(parent_task_runner_->BelongsToCurrentThread());
288 registrar_.UnregisterHandler(handler);
289}
290
[email protected]08a6f9992012-09-07 19:19:16291InvalidatorState NonBlockingInvalidator::GetInvalidatorState() const {
292 DCHECK(parent_task_runner_->BelongsToCurrentThread());
293 return registrar_.GetInvalidatorState();
294}
295
[email protected]a329cb82012-08-28 03:17:58296void NonBlockingInvalidator::UpdateCredentials(const std::string& email,
297 const std::string& token) {
[email protected]4969b0122012-06-16 01:58:28298 DCHECK(parent_task_runner_->BelongsToCurrentThread());
299 if (!network_task_runner_->PostTask(
[email protected]daf4e102011-04-26 08:30:28300 FROM_HERE,
[email protected]a329cb82012-08-28 03:17:58301 base::Bind(&NonBlockingInvalidator::Core::UpdateCredentials,
[email protected]09e170f2011-10-28 23:22:02302 core_.get(), email, token))) {
[email protected]daf4e102011-04-26 08:30:28303 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18304 }
[email protected]0a80fed2011-03-24 22:31:48305}
306
[email protected]5cb5b182014-03-18 00:32:39307void NonBlockingInvalidator::RequestDetailedStatus(
[email protected]40848a92014-03-24 22:41:02308 base::Callback<void(const base::DictionaryValue&)> callback) const {
[email protected]5cb5b182014-03-18 00:32:39309 DCHECK(parent_task_runner_->BelongsToCurrentThread());
310 base::Callback<void(const base::DictionaryValue&)> proxy_callback =
311 base::Bind(&CallbackProxy::Run, base::Owned(new CallbackProxy(callback)));
312 if (!network_task_runner_->PostTask(
313 FROM_HERE,
314 base::Bind(&NonBlockingInvalidator::Core::RequestDetailedStatus,
315 core_.get(),
316 proxy_callback))) {
317 NOTREACHED();
318 }
319}
320
[email protected]04a830a2014-01-04 02:48:51321NetworkChannelCreator
322 NonBlockingInvalidator::MakePushClientChannelCreator(
323 const notifier::NotifierOptions& notifier_options) {
324 return base::Bind(SyncNetworkChannel::CreatePushClientChannel,
325 notifier_options);
326}
327
[email protected]df006cbc2014-01-22 18:36:20328NetworkChannelCreator NonBlockingInvalidator::MakeGCMNetworkChannelCreator(
329 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
330 scoped_ptr<GCMNetworkChannelDelegate> delegate) {
331 return base::Bind(&SyncNetworkChannel::CreateGCMNetworkChannel,
332 request_context_getter,
333 base::Passed(&delegate));
[email protected]04a830a2014-01-04 02:48:51334}
335
[email protected]3ee8ec72014-04-16 21:38:50336void NonBlockingInvalidator::ClearAndSetNewClientId(const std::string& data) {
337 DCHECK(parent_task_runner_->BelongsToCurrentThread());
338 invalidation_state_tracker_->ClearAndSetNewClientId(data);
339}
340
341std::string NonBlockingInvalidator::GetInvalidatorClientId() const {
342 DCHECK(parent_task_runner_->BelongsToCurrentThread());
343 return invalidation_state_tracker_->GetInvalidatorClientId();
344}
345
346void NonBlockingInvalidator::SetBootstrapData(const std::string& data) {
347 DCHECK(parent_task_runner_->BelongsToCurrentThread());
348 invalidation_state_tracker_->SetBootstrapData(data);
349}
350
351std::string NonBlockingInvalidator::GetBootstrapData() const {
352 DCHECK(parent_task_runner_->BelongsToCurrentThread());
353 return invalidation_state_tracker_->GetBootstrapData();
354}
355
356void NonBlockingInvalidator::SetSavedInvalidations(
357 const UnackedInvalidationsMap& states) {
358 DCHECK(parent_task_runner_->BelongsToCurrentThread());
359 invalidation_state_tracker_->SetSavedInvalidations(states);
360}
361
362UnackedInvalidationsMap NonBlockingInvalidator::GetSavedInvalidations() const {
363 DCHECK(parent_task_runner_->BelongsToCurrentThread());
364 return invalidation_state_tracker_->GetSavedInvalidations();
365}
366
367void NonBlockingInvalidator::Clear() {
368 DCHECK(parent_task_runner_->BelongsToCurrentThread());
369 invalidation_state_tracker_->Clear();
370}
371
372void NonBlockingInvalidator::OnInvalidatorStateChange(InvalidatorState state) {
373 DCHECK(parent_task_runner_->BelongsToCurrentThread());
374 registrar_.UpdateInvalidatorState(state);
375}
376
377void NonBlockingInvalidator::OnIncomingInvalidation(
378 const ObjectIdInvalidationMap& invalidation_map) {
379 DCHECK(parent_task_runner_->BelongsToCurrentThread());
380 registrar_.DispatchInvalidationsToHandlers(invalidation_map);
381}
382
383std::string NonBlockingInvalidator::GetOwnerName() const { return "Sync"; }
384
[email protected]65f173552012-06-28 22:43:58385} // namespace syncer