blob: 8830a2331f39fc2e229e58d3b002659f096b4a5b [file] [log] [blame]
[email protected]6990e4e02012-01-26 00:44:531// Copyright (c) 2012 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]b7fe4b52012-04-19 14:21:095#include "sync/notifier/non_blocking_invalidation_notifier.h"
[email protected]0a80fed2011-03-24 22:31:486
7#include "base/logging.h"
[email protected]942e2022011-04-07 22:27:438#include "base/memory/scoped_ptr.h"
[email protected]0a80fed2011-03-24 22:31:489#include "base/message_loop.h"
[email protected]942e2022011-04-07 22:27:4310#include "base/threading/thread.h"
[email protected]b7fe4b52012-04-19 14:21:0911#include "sync/notifier/invalidation_notifier.h"
[email protected]0a80fed2011-03-24 22:31:4812
13namespace sync_notifier {
14
[email protected]942e2022011-04-07 22:27:4315class NonBlockingInvalidationNotifier::Core
16 : public base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>,
[email protected]7800d792012-05-30 02:34:4817 // SyncNotifierObserver to observe the InvalidationNotifier we create.
[email protected]942e2022011-04-07 22:27:4318 public SyncNotifierObserver {
19 public:
[email protected]b9908a242011-11-19 09:31:3220 // Called on parent thread. |delegate_observer| should be
21 // initialized.
22 explicit Core(
23 const browser_sync::WeakHandle<SyncNotifierObserver>&
24 delegate_observer);
[email protected]942e2022011-04-07 22:27:4325
26 // Helpers called on I/O thread.
[email protected]e3b0ee52011-10-12 03:04:1327 void Initialize(
28 const notifier::NotifierOptions& notifier_options,
29 const InvalidationVersionMap& initial_max_invalidation_versions,
[email protected]46e43ee2012-05-18 19:24:4130 const browser_sync::WeakHandle<InvalidationStateTracker>&
31 invalidation_state_tracker,
[email protected]e3b0ee52011-10-12 03:04:1332 const std::string& client_info);
[email protected]942e2022011-04-07 22:27:4333 void Teardown();
[email protected]0a5612052011-06-29 03:29:1834 void SetUniqueId(const std::string& unique_id);
[email protected]942e2022011-04-07 22:27:4335 void SetState(const std::string& state);
36 void UpdateCredentials(const std::string& email, const std::string& token);
[email protected]400f521a2011-12-13 01:50:2337 void UpdateEnabledTypes(syncable::ModelTypeSet enabled_types);
[email protected]942e2022011-04-07 22:27:4338
[email protected]7800d792012-05-30 02:34:4839 // SyncNotifierObserver implementation (all called on I/O thread by
40 // InvalidationNotifier).
[email protected]942e2022011-04-07 22:27:4341 virtual void OnIncomingNotification(
[email protected]6990e4e02012-01-26 00:44:5342 const syncable::ModelTypePayloadMap& type_payloads,
43 IncomingNotificationSource source);
[email protected]942e2022011-04-07 22:27:4344 virtual void OnNotificationStateChange(bool notifications_enabled);
45 virtual void StoreState(const std::string& state);
46
47 private:
48 friend class
49 base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>;
50 // Called on parent or I/O thread.
51 ~Core();
52
[email protected]b9908a242011-11-19 09:31:3253 // The variables below should be used only on the I/O thread.
54 const browser_sync::WeakHandle<SyncNotifierObserver> delegate_observer_;
[email protected]942e2022011-04-07 22:27:4355 scoped_ptr<InvalidationNotifier> invalidation_notifier_;
56 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
[email protected]b9908a242011-11-19 09:31:3257
[email protected]942e2022011-04-07 22:27:4358 DISALLOW_COPY_AND_ASSIGN(Core);
59};
60
[email protected]b9908a242011-11-19 09:31:3261NonBlockingInvalidationNotifier::Core::Core(
62 const browser_sync::WeakHandle<SyncNotifierObserver>&
63 delegate_observer)
64 : delegate_observer_(delegate_observer) {
65 DCHECK(delegate_observer_.IsInitialized());
[email protected]942e2022011-04-07 22:27:4366}
67
68NonBlockingInvalidationNotifier::Core::~Core() {
69}
70
71void NonBlockingInvalidationNotifier::Core::Initialize(
72 const notifier::NotifierOptions& notifier_options,
[email protected]e3b0ee52011-10-12 03:04:1373 const InvalidationVersionMap& initial_max_invalidation_versions,
[email protected]46e43ee2012-05-18 19:24:4174 const browser_sync::WeakHandle<InvalidationStateTracker>&
75 invalidation_state_tracker,
[email protected]942e2022011-04-07 22:27:4376 const std::string& client_info) {
77 DCHECK(notifier_options.request_context_getter);
78 DCHECK_EQ(notifier::NOTIFICATION_SERVER,
79 notifier_options.notification_method);
80 io_message_loop_proxy_ = notifier_options.request_context_getter->
81 GetIOMessageLoopProxy();
82 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
83 invalidation_notifier_.reset(
[email protected]e3b0ee52011-10-12 03:04:1384 new InvalidationNotifier(
85 notifier_options,
86 initial_max_invalidation_versions,
[email protected]46e43ee2012-05-18 19:24:4187 invalidation_state_tracker,
[email protected]e3b0ee52011-10-12 03:04:1388 client_info));
[email protected]942e2022011-04-07 22:27:4389 invalidation_notifier_->AddObserver(this);
90}
91
92
93void NonBlockingInvalidationNotifier::Core::Teardown() {
94 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
95 invalidation_notifier_->RemoveObserver(this);
96 invalidation_notifier_.reset();
97 io_message_loop_proxy_ = NULL;
98}
99
[email protected]0a5612052011-06-29 03:29:18100void NonBlockingInvalidationNotifier::Core::SetUniqueId(
101 const std::string& unique_id) {
102 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
103 invalidation_notifier_->SetUniqueId(unique_id);
104}
105
[email protected]942e2022011-04-07 22:27:43106void NonBlockingInvalidationNotifier::Core::SetState(
107 const std::string& state) {
108 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
109 invalidation_notifier_->SetState(state);
110}
111
112void NonBlockingInvalidationNotifier::Core::UpdateCredentials(
113 const std::string& email, const std::string& token) {
114 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
115 invalidation_notifier_->UpdateCredentials(email, token);
116}
117
118void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes(
[email protected]400f521a2011-12-13 01:50:23119 syncable::ModelTypeSet enabled_types) {
[email protected]942e2022011-04-07 22:27:43120 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
[email protected]2f15fd0e2011-08-27 05:29:09121 invalidation_notifier_->UpdateEnabledTypes(enabled_types);
[email protected]942e2022011-04-07 22:27:43122}
123
124void NonBlockingInvalidationNotifier::Core::OnIncomingNotification(
[email protected]6990e4e02012-01-26 00:44:53125 const syncable::ModelTypePayloadMap& type_payloads,
126 IncomingNotificationSource source) {
[email protected]942e2022011-04-07 22:27:43127 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
[email protected]b9908a242011-11-19 09:31:32128 delegate_observer_.Call(FROM_HERE,
129 &SyncNotifierObserver::OnIncomingNotification,
[email protected]6990e4e02012-01-26 00:44:53130 type_payloads,
131 source);
[email protected]942e2022011-04-07 22:27:43132}
133
134void NonBlockingInvalidationNotifier::Core::OnNotificationStateChange(
135 bool notifications_enabled) {
136 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
[email protected]b9908a242011-11-19 09:31:32137 delegate_observer_.Call(FROM_HERE,
138 &SyncNotifierObserver::OnNotificationStateChange,
139 notifications_enabled);
[email protected]942e2022011-04-07 22:27:43140}
141
142void NonBlockingInvalidationNotifier::Core::StoreState(
143 const std::string& state) {
144 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
[email protected]b9908a242011-11-19 09:31:32145 delegate_observer_.Call(FROM_HERE,
146 &SyncNotifierObserver::StoreState, state);
[email protected]942e2022011-04-07 22:27:43147}
148
[email protected]0a80fed2011-03-24 22:31:48149NonBlockingInvalidationNotifier::NonBlockingInvalidationNotifier(
150 const notifier::NotifierOptions& notifier_options,
[email protected]e3b0ee52011-10-12 03:04:13151 const InvalidationVersionMap& initial_max_invalidation_versions,
[email protected]46e43ee2012-05-18 19:24:41152 const browser_sync::WeakHandle<InvalidationStateTracker>&
153 invalidation_state_tracker,
[email protected]0a80fed2011-03-24 22:31:48154 const std::string& client_info)
[email protected]b9908a242011-11-19 09:31:32155 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
156 core_(
157 new Core(browser_sync::MakeWeakHandle(
158 weak_ptr_factory_.GetWeakPtr()))),
[email protected]f9682402011-06-28 22:34:27159 parent_message_loop_proxy_(
[email protected]edd685f2011-08-15 20:33:46160 base::MessageLoopProxy::current()),
[email protected]942e2022011-04-07 22:27:43161 io_message_loop_proxy_(notifier_options.request_context_getter->
162 GetIOMessageLoopProxy()) {
[email protected]daf4e102011-04-26 08:30:28163 if (!io_message_loop_proxy_->PostTask(
164 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02165 base::Bind(
[email protected]daf4e102011-04-26 08:30:28166 &NonBlockingInvalidationNotifier::Core::Initialize,
[email protected]09e170f2011-10-28 23:22:02167 core_.get(),
[email protected]e3b0ee52011-10-12 03:04:13168 notifier_options,
169 initial_max_invalidation_versions,
[email protected]46e43ee2012-05-18 19:24:41170 invalidation_state_tracker,
[email protected]e3b0ee52011-10-12 03:04:13171 client_info))) {
[email protected]daf4e102011-04-26 08:30:28172 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18173 }
[email protected]0a80fed2011-03-24 22:31:48174}
175
176NonBlockingInvalidationNotifier::~NonBlockingInvalidationNotifier() {
[email protected]f9682402011-06-28 22:34:27177 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]daf4e102011-04-26 08:30:28178 if (!io_message_loop_proxy_->PostTask(
179 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02180 base::Bind(&NonBlockingInvalidationNotifier::Core::Teardown,
181 core_.get()))) {
[email protected]daf4e102011-04-26 08:30:28182 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18183 }
[email protected]0a80fed2011-03-24 22:31:48184}
185
186void NonBlockingInvalidationNotifier::AddObserver(
187 SyncNotifierObserver* observer) {
[email protected]f9682402011-06-28 22:34:27188 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]b9908a242011-11-19 09:31:32189 observers_.AddObserver(observer);
[email protected]0a80fed2011-03-24 22:31:48190}
191
192void NonBlockingInvalidationNotifier::RemoveObserver(
193 SyncNotifierObserver* observer) {
[email protected]f9682402011-06-28 22:34:27194 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]b9908a242011-11-19 09:31:32195 observers_.RemoveObserver(observer);
[email protected]0a80fed2011-03-24 22:31:48196}
197
[email protected]0a5612052011-06-29 03:29:18198void NonBlockingInvalidationNotifier::SetUniqueId(
199 const std::string& unique_id) {
200 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
201 if (!io_message_loop_proxy_->PostTask(
202 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02203 base::Bind(&NonBlockingInvalidationNotifier::Core::SetUniqueId,
204 core_.get(), unique_id))) {
[email protected]0a5612052011-06-29 03:29:18205 NOTREACHED();
206 }
207}
208
[email protected]0a80fed2011-03-24 22:31:48209void NonBlockingInvalidationNotifier::SetState(const std::string& state) {
[email protected]f9682402011-06-28 22:34:27210 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]daf4e102011-04-26 08:30:28211 if (!io_message_loop_proxy_->PostTask(
212 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02213 base::Bind(&NonBlockingInvalidationNotifier::Core::SetState,
214 core_.get(), state))) {
[email protected]daf4e102011-04-26 08:30:28215 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18216 }
[email protected]0a80fed2011-03-24 22:31:48217}
218
219void NonBlockingInvalidationNotifier::UpdateCredentials(
220 const std::string& email, const std::string& token) {
[email protected]f9682402011-06-28 22:34:27221 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]daf4e102011-04-26 08:30:28222 if (!io_message_loop_proxy_->PostTask(
223 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02224 base::Bind(&NonBlockingInvalidationNotifier::Core::UpdateCredentials,
225 core_.get(), email, token))) {
[email protected]daf4e102011-04-26 08:30:28226 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18227 }
[email protected]0a80fed2011-03-24 22:31:48228}
229
230void NonBlockingInvalidationNotifier::UpdateEnabledTypes(
[email protected]400f521a2011-12-13 01:50:23231 syncable::ModelTypeSet enabled_types) {
[email protected]f9682402011-06-28 22:34:27232 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]daf4e102011-04-26 08:30:28233 if (!io_message_loop_proxy_->PostTask(
234 FROM_HERE,
[email protected]09e170f2011-10-28 23:22:02235 base::Bind(&NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes,
236 core_.get(), enabled_types))) {
[email protected]daf4e102011-04-26 08:30:28237 NOTREACHED();
[email protected]0a5612052011-06-29 03:29:18238 }
[email protected]0a80fed2011-03-24 22:31:48239}
240
[email protected]2f15fd0e2011-08-27 05:29:09241void NonBlockingInvalidationNotifier::SendNotification(
[email protected]400f521a2011-12-13 01:50:23242 syncable::ModelTypeSet changed_types) {
[email protected]f9682402011-06-28 22:34:27243 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
[email protected]0a80fed2011-03-24 22:31:48244 // InvalidationClient doesn't implement SendNotification(), so no
245 // need to forward on the call.
246}
247
[email protected]b9908a242011-11-19 09:31:32248void NonBlockingInvalidationNotifier::OnIncomingNotification(
[email protected]6990e4e02012-01-26 00:44:53249 const syncable::ModelTypePayloadMap& type_payloads,
250 IncomingNotificationSource source) {
[email protected]b9908a242011-11-19 09:31:32251 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
252 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_,
[email protected]6990e4e02012-01-26 00:44:53253 OnIncomingNotification(type_payloads, source));
[email protected]b9908a242011-11-19 09:31:32254}
255
256void NonBlockingInvalidationNotifier::OnNotificationStateChange(
257 bool notifications_enabled) {
258 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
259 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_,
260 OnNotificationStateChange(notifications_enabled));
261}
262
263void NonBlockingInvalidationNotifier::StoreState(
264 const std::string& state) {
265 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread());
266 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_,
267 StoreState(state));
268}
269
[email protected]0a80fed2011-03-24 22:31:48270} // namespace sync_notifier