OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/notifier/non_blocking_invalidation_notifier.h" | 5 #include "chrome/browser/sync/notifier/non_blocking_invalidation_notifier.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/observer_list_threadsafe.h" | |
11 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
12 #include "chrome/browser/sync/notifier/invalidation_notifier.h" | 11 #include "chrome/browser/sync/notifier/invalidation_notifier.h" |
13 #include "chrome/browser/sync/notifier/sync_notifier_observer.h" | |
14 | 12 |
15 namespace sync_notifier { | 13 namespace sync_notifier { |
16 | 14 |
17 class NonBlockingInvalidationNotifier::Core | 15 class NonBlockingInvalidationNotifier::Core |
18 : public base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>, | 16 : public base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>, |
19 public SyncNotifierObserver { | 17 public SyncNotifierObserver { |
20 public: | 18 public: |
21 // Called on parent thread. | 19 // Called on parent thread. |delegate_observer| should be |
22 Core(); | 20 // initialized. |
23 | 21 explicit Core( |
24 // Called on parent thread. | 22 const browser_sync::WeakHandle<SyncNotifierObserver>& |
25 void AddObserver(SyncNotifierObserver* observer); | 23 delegate_observer); |
26 void RemoveObserver(SyncNotifierObserver* observer); | |
27 | 24 |
28 // Helpers called on I/O thread. | 25 // Helpers called on I/O thread. |
29 void Initialize( | 26 void Initialize( |
30 const notifier::NotifierOptions& notifier_options, | 27 const notifier::NotifierOptions& notifier_options, |
31 const InvalidationVersionMap& initial_max_invalidation_versions, | 28 const InvalidationVersionMap& initial_max_invalidation_versions, |
32 const browser_sync::WeakHandle<InvalidationVersionTracker>& | 29 const browser_sync::WeakHandle<InvalidationVersionTracker>& |
33 invalidation_version_tracker, | 30 invalidation_version_tracker, |
34 const std::string& client_info); | 31 const std::string& client_info); |
35 void Teardown(); | 32 void Teardown(); |
36 void SetUniqueId(const std::string& unique_id); | 33 void SetUniqueId(const std::string& unique_id); |
37 void SetState(const std::string& state); | 34 void SetState(const std::string& state); |
38 void UpdateCredentials(const std::string& email, const std::string& token); | 35 void UpdateCredentials(const std::string& email, const std::string& token); |
39 void UpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); | 36 void UpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); |
40 | 37 |
41 // SyncNotifierObserver implementation (all called on I/O thread). | 38 // SyncNotifierObserver implementation (all called on I/O thread). |
42 virtual void OnIncomingNotification( | 39 virtual void OnIncomingNotification( |
43 const syncable::ModelTypePayloadMap& type_payloads); | 40 const syncable::ModelTypePayloadMap& type_payloads); |
44 virtual void OnNotificationStateChange(bool notifications_enabled); | 41 virtual void OnNotificationStateChange(bool notifications_enabled); |
45 virtual void StoreState(const std::string& state); | 42 virtual void StoreState(const std::string& state); |
46 | 43 |
47 private: | 44 private: |
48 friend class | 45 friend class |
49 base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>; | 46 base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>; |
50 // Called on parent or I/O thread. | 47 // Called on parent or I/O thread. |
51 ~Core(); | 48 ~Core(); |
52 | 49 |
| 50 // The variables below should be used only on the I/O thread. |
| 51 const browser_sync::WeakHandle<SyncNotifierObserver> delegate_observer_; |
53 scoped_ptr<InvalidationNotifier> invalidation_notifier_; | 52 scoped_ptr<InvalidationNotifier> invalidation_notifier_; |
54 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 53 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
55 scoped_refptr<ObserverListThreadSafe<SyncNotifierObserver> > observers_; | 54 |
56 DISALLOW_COPY_AND_ASSIGN(Core); | 55 DISALLOW_COPY_AND_ASSIGN(Core); |
57 }; | 56 }; |
58 | 57 |
59 NonBlockingInvalidationNotifier::Core::Core() | 58 NonBlockingInvalidationNotifier::Core::Core( |
60 : observers_(new ObserverListThreadSafe<SyncNotifierObserver>()) { | 59 const browser_sync::WeakHandle<SyncNotifierObserver>& |
| 60 delegate_observer) |
| 61 : delegate_observer_(delegate_observer) { |
| 62 DCHECK(delegate_observer_.IsInitialized()); |
61 } | 63 } |
62 | 64 |
63 NonBlockingInvalidationNotifier::Core::~Core() { | 65 NonBlockingInvalidationNotifier::Core::~Core() { |
64 } | 66 } |
65 | 67 |
66 void NonBlockingInvalidationNotifier::Core::Initialize( | 68 void NonBlockingInvalidationNotifier::Core::Initialize( |
67 const notifier::NotifierOptions& notifier_options, | 69 const notifier::NotifierOptions& notifier_options, |
68 const InvalidationVersionMap& initial_max_invalidation_versions, | 70 const InvalidationVersionMap& initial_max_invalidation_versions, |
69 const browser_sync::WeakHandle<InvalidationVersionTracker>& | 71 const browser_sync::WeakHandle<InvalidationVersionTracker>& |
70 invalidation_version_tracker, | 72 invalidation_version_tracker, |
(...skipping 14 matching lines...) Expand all Loading... |
85 } | 87 } |
86 | 88 |
87 | 89 |
88 void NonBlockingInvalidationNotifier::Core::Teardown() { | 90 void NonBlockingInvalidationNotifier::Core::Teardown() { |
89 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 91 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
90 invalidation_notifier_->RemoveObserver(this); | 92 invalidation_notifier_->RemoveObserver(this); |
91 invalidation_notifier_.reset(); | 93 invalidation_notifier_.reset(); |
92 io_message_loop_proxy_ = NULL; | 94 io_message_loop_proxy_ = NULL; |
93 } | 95 } |
94 | 96 |
95 void NonBlockingInvalidationNotifier::Core::AddObserver( | |
96 SyncNotifierObserver* observer) { | |
97 observers_->AddObserver(observer); | |
98 } | |
99 | |
100 void NonBlockingInvalidationNotifier::Core::RemoveObserver( | |
101 SyncNotifierObserver* observer) { | |
102 observers_->RemoveObserver(observer); | |
103 } | |
104 | |
105 void NonBlockingInvalidationNotifier::Core::SetUniqueId( | 97 void NonBlockingInvalidationNotifier::Core::SetUniqueId( |
106 const std::string& unique_id) { | 98 const std::string& unique_id) { |
107 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 99 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
108 invalidation_notifier_->SetUniqueId(unique_id); | 100 invalidation_notifier_->SetUniqueId(unique_id); |
109 } | 101 } |
110 | 102 |
111 void NonBlockingInvalidationNotifier::Core::SetState( | 103 void NonBlockingInvalidationNotifier::Core::SetState( |
112 const std::string& state) { | 104 const std::string& state) { |
113 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 105 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
114 invalidation_notifier_->SetState(state); | 106 invalidation_notifier_->SetState(state); |
115 } | 107 } |
116 | 108 |
117 void NonBlockingInvalidationNotifier::Core::UpdateCredentials( | 109 void NonBlockingInvalidationNotifier::Core::UpdateCredentials( |
118 const std::string& email, const std::string& token) { | 110 const std::string& email, const std::string& token) { |
119 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 111 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
120 invalidation_notifier_->UpdateCredentials(email, token); | 112 invalidation_notifier_->UpdateCredentials(email, token); |
121 } | 113 } |
122 | 114 |
123 void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes( | 115 void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes( |
124 const syncable::ModelTypeSet& enabled_types) { | 116 const syncable::ModelTypeSet& enabled_types) { |
125 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 117 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
126 invalidation_notifier_->UpdateEnabledTypes(enabled_types); | 118 invalidation_notifier_->UpdateEnabledTypes(enabled_types); |
127 } | 119 } |
128 | 120 |
129 void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( | 121 void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( |
130 const syncable::ModelTypePayloadMap& type_payloads) { | 122 const syncable::ModelTypePayloadMap& type_payloads) { |
131 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 123 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
132 observers_->Notify(&SyncNotifierObserver::OnIncomingNotification, | 124 delegate_observer_.Call(FROM_HERE, |
133 type_payloads); | 125 &SyncNotifierObserver::OnIncomingNotification, |
| 126 type_payloads); |
134 } | 127 } |
135 | 128 |
136 void NonBlockingInvalidationNotifier::Core::OnNotificationStateChange( | 129 void NonBlockingInvalidationNotifier::Core::OnNotificationStateChange( |
137 bool notifications_enabled) { | 130 bool notifications_enabled) { |
138 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 131 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
139 observers_->Notify(&SyncNotifierObserver::OnNotificationStateChange, | 132 delegate_observer_.Call(FROM_HERE, |
140 notifications_enabled); | 133 &SyncNotifierObserver::OnNotificationStateChange, |
| 134 notifications_enabled); |
141 } | 135 } |
142 | 136 |
143 void NonBlockingInvalidationNotifier::Core::StoreState( | 137 void NonBlockingInvalidationNotifier::Core::StoreState( |
144 const std::string& state) { | 138 const std::string& state) { |
145 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 139 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
146 observers_->Notify(&SyncNotifierObserver::StoreState, state); | 140 delegate_observer_.Call(FROM_HERE, |
| 141 &SyncNotifierObserver::StoreState, state); |
147 } | 142 } |
148 | 143 |
149 NonBlockingInvalidationNotifier::NonBlockingInvalidationNotifier( | 144 NonBlockingInvalidationNotifier::NonBlockingInvalidationNotifier( |
150 const notifier::NotifierOptions& notifier_options, | 145 const notifier::NotifierOptions& notifier_options, |
151 const InvalidationVersionMap& initial_max_invalidation_versions, | 146 const InvalidationVersionMap& initial_max_invalidation_versions, |
152 const browser_sync::WeakHandle<InvalidationVersionTracker>& | 147 const browser_sync::WeakHandle<InvalidationVersionTracker>& |
153 invalidation_version_tracker, | 148 invalidation_version_tracker, |
154 const std::string& client_info) | 149 const std::string& client_info) |
155 : core_(new Core), | 150 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 151 core_( |
| 152 new Core(browser_sync::MakeWeakHandle( |
| 153 weak_ptr_factory_.GetWeakPtr()))), |
156 parent_message_loop_proxy_( | 154 parent_message_loop_proxy_( |
157 base::MessageLoopProxy::current()), | 155 base::MessageLoopProxy::current()), |
158 io_message_loop_proxy_(notifier_options.request_context_getter-> | 156 io_message_loop_proxy_(notifier_options.request_context_getter-> |
159 GetIOMessageLoopProxy()) { | 157 GetIOMessageLoopProxy()) { |
160 if (!io_message_loop_proxy_->PostTask( | 158 if (!io_message_loop_proxy_->PostTask( |
161 FROM_HERE, | 159 FROM_HERE, |
162 base::Bind( | 160 base::Bind( |
163 &NonBlockingInvalidationNotifier::Core::Initialize, | 161 &NonBlockingInvalidationNotifier::Core::Initialize, |
164 core_.get(), | 162 core_.get(), |
165 notifier_options, | 163 notifier_options, |
(...skipping 10 matching lines...) Expand all Loading... |
176 FROM_HERE, | 174 FROM_HERE, |
177 base::Bind(&NonBlockingInvalidationNotifier::Core::Teardown, | 175 base::Bind(&NonBlockingInvalidationNotifier::Core::Teardown, |
178 core_.get()))) { | 176 core_.get()))) { |
179 NOTREACHED(); | 177 NOTREACHED(); |
180 } | 178 } |
181 } | 179 } |
182 | 180 |
183 void NonBlockingInvalidationNotifier::AddObserver( | 181 void NonBlockingInvalidationNotifier::AddObserver( |
184 SyncNotifierObserver* observer) { | 182 SyncNotifierObserver* observer) { |
185 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 183 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
186 core_->AddObserver(observer); | 184 observers_.AddObserver(observer); |
187 } | 185 } |
188 | 186 |
189 void NonBlockingInvalidationNotifier::RemoveObserver( | 187 void NonBlockingInvalidationNotifier::RemoveObserver( |
190 SyncNotifierObserver* observer) { | 188 SyncNotifierObserver* observer) { |
191 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 189 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
192 core_->RemoveObserver(observer); | 190 observers_.RemoveObserver(observer); |
193 } | 191 } |
194 | 192 |
195 void NonBlockingInvalidationNotifier::SetUniqueId( | 193 void NonBlockingInvalidationNotifier::SetUniqueId( |
196 const std::string& unique_id) { | 194 const std::string& unique_id) { |
197 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 195 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
198 if (!io_message_loop_proxy_->PostTask( | 196 if (!io_message_loop_proxy_->PostTask( |
199 FROM_HERE, | 197 FROM_HERE, |
200 base::Bind(&NonBlockingInvalidationNotifier::Core::SetUniqueId, | 198 base::Bind(&NonBlockingInvalidationNotifier::Core::SetUniqueId, |
201 core_.get(), unique_id))) { | 199 core_.get(), unique_id))) { |
202 NOTREACHED(); | 200 NOTREACHED(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 } | 233 } |
236 } | 234 } |
237 | 235 |
238 void NonBlockingInvalidationNotifier::SendNotification( | 236 void NonBlockingInvalidationNotifier::SendNotification( |
239 const syncable::ModelTypeSet& changed_types) { | 237 const syncable::ModelTypeSet& changed_types) { |
240 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 238 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
241 // InvalidationClient doesn't implement SendNotification(), so no | 239 // InvalidationClient doesn't implement SendNotification(), so no |
242 // need to forward on the call. | 240 // need to forward on the call. |
243 } | 241 } |
244 | 242 |
| 243 void NonBlockingInvalidationNotifier::OnIncomingNotification( |
| 244 const syncable::ModelTypePayloadMap& type_payloads) { |
| 245 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 246 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, |
| 247 OnIncomingNotification(type_payloads)); |
| 248 } |
| 249 |
| 250 void NonBlockingInvalidationNotifier::OnNotificationStateChange( |
| 251 bool notifications_enabled) { |
| 252 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 253 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, |
| 254 OnNotificationStateChange(notifications_enabled)); |
| 255 } |
| 256 |
| 257 void NonBlockingInvalidationNotifier::StoreState( |
| 258 const std::string& state) { |
| 259 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 260 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, |
| 261 StoreState(state)); |
| 262 } |
| 263 |
245 } // namespace sync_notifier | 264 } // namespace sync_notifier |
OLD | NEW |