[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | b7fe4b5 | 2012-04-19 14:21:09 | [diff] [blame] | 5 | #include "sync/notifier/non_blocking_invalidation_notifier.h" |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 6 | |
| 7 | #include "base/logging.h" |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 8 | #include "base/memory/scoped_ptr.h" |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 9 | #include "base/message_loop.h" |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 10 | #include "base/threading/thread.h" |
[email protected] | b7fe4b5 | 2012-04-19 14:21:09 | [diff] [blame] | 11 | #include "sync/notifier/invalidation_notifier.h" |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 12 | |
| 13 | namespace sync_notifier { |
| 14 | |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 15 | class NonBlockingInvalidationNotifier::Core |
| 16 | : public base::RefCountedThreadSafe<NonBlockingInvalidationNotifier::Core>, |
[email protected] | 7800d79 | 2012-05-30 02:34:48 | [diff] [blame^] | 17 | // SyncNotifierObserver to observe the InvalidationNotifier we create. |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 18 | public SyncNotifierObserver { |
| 19 | public: |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 20 | // Called on parent thread. |delegate_observer| should be |
| 21 | // initialized. |
| 22 | explicit Core( |
| 23 | const browser_sync::WeakHandle<SyncNotifierObserver>& |
| 24 | delegate_observer); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 25 | |
| 26 | // Helpers called on I/O thread. |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 27 | void Initialize( |
| 28 | const notifier::NotifierOptions& notifier_options, |
| 29 | const InvalidationVersionMap& initial_max_invalidation_versions, |
[email protected] | 46e43ee | 2012-05-18 19:24:41 | [diff] [blame] | 30 | const browser_sync::WeakHandle<InvalidationStateTracker>& |
| 31 | invalidation_state_tracker, |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 32 | const std::string& client_info); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 33 | void Teardown(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 34 | void SetUniqueId(const std::string& unique_id); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 35 | void SetState(const std::string& state); |
| 36 | void UpdateCredentials(const std::string& email, const std::string& token); |
[email protected] | 400f521a | 2011-12-13 01:50:23 | [diff] [blame] | 37 | void UpdateEnabledTypes(syncable::ModelTypeSet enabled_types); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 38 | |
[email protected] | 7800d79 | 2012-05-30 02:34:48 | [diff] [blame^] | 39 | // SyncNotifierObserver implementation (all called on I/O thread by |
| 40 | // InvalidationNotifier). |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 41 | virtual void OnIncomingNotification( |
[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 42 | const syncable::ModelTypePayloadMap& type_payloads, |
| 43 | IncomingNotificationSource source); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 44 | 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] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 53 | // The variables below should be used only on the I/O thread. |
| 54 | const browser_sync::WeakHandle<SyncNotifierObserver> delegate_observer_; |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 55 | scoped_ptr<InvalidationNotifier> invalidation_notifier_; |
| 56 | scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 57 | |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 58 | DISALLOW_COPY_AND_ASSIGN(Core); |
| 59 | }; |
| 60 | |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 61 | NonBlockingInvalidationNotifier::Core::Core( |
| 62 | const browser_sync::WeakHandle<SyncNotifierObserver>& |
| 63 | delegate_observer) |
| 64 | : delegate_observer_(delegate_observer) { |
| 65 | DCHECK(delegate_observer_.IsInitialized()); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | NonBlockingInvalidationNotifier::Core::~Core() { |
| 69 | } |
| 70 | |
| 71 | void NonBlockingInvalidationNotifier::Core::Initialize( |
| 72 | const notifier::NotifierOptions& notifier_options, |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 73 | const InvalidationVersionMap& initial_max_invalidation_versions, |
[email protected] | 46e43ee | 2012-05-18 19:24:41 | [diff] [blame] | 74 | const browser_sync::WeakHandle<InvalidationStateTracker>& |
| 75 | invalidation_state_tracker, |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 76 | 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] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 84 | new InvalidationNotifier( |
| 85 | notifier_options, |
| 86 | initial_max_invalidation_versions, |
[email protected] | 46e43ee | 2012-05-18 19:24:41 | [diff] [blame] | 87 | invalidation_state_tracker, |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 88 | client_info)); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 89 | invalidation_notifier_->AddObserver(this); |
| 90 | } |
| 91 | |
| 92 | |
| 93 | void 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] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 100 | void 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] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 106 | void NonBlockingInvalidationNotifier::Core::SetState( |
| 107 | const std::string& state) { |
| 108 | DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 109 | invalidation_notifier_->SetState(state); |
| 110 | } |
| 111 | |
| 112 | void 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 | |
| 118 | void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes( |
[email protected] | 400f521a | 2011-12-13 01:50:23 | [diff] [blame] | 119 | syncable::ModelTypeSet enabled_types) { |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 120 | DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | 2f15fd0e | 2011-08-27 05:29:09 | [diff] [blame] | 121 | invalidation_notifier_->UpdateEnabledTypes(enabled_types); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( |
[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 125 | const syncable::ModelTypePayloadMap& type_payloads, |
| 126 | IncomingNotificationSource source) { |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 127 | DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 128 | delegate_observer_.Call(FROM_HERE, |
| 129 | &SyncNotifierObserver::OnIncomingNotification, |
[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 130 | type_payloads, |
| 131 | source); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | void NonBlockingInvalidationNotifier::Core::OnNotificationStateChange( |
| 135 | bool notifications_enabled) { |
| 136 | DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 137 | delegate_observer_.Call(FROM_HERE, |
| 138 | &SyncNotifierObserver::OnNotificationStateChange, |
| 139 | notifications_enabled); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | void NonBlockingInvalidationNotifier::Core::StoreState( |
| 143 | const std::string& state) { |
| 144 | DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 145 | delegate_observer_.Call(FROM_HERE, |
| 146 | &SyncNotifierObserver::StoreState, state); |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 147 | } |
| 148 | |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 149 | NonBlockingInvalidationNotifier::NonBlockingInvalidationNotifier( |
| 150 | const notifier::NotifierOptions& notifier_options, |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 151 | const InvalidationVersionMap& initial_max_invalidation_versions, |
[email protected] | 46e43ee | 2012-05-18 19:24:41 | [diff] [blame] | 152 | const browser_sync::WeakHandle<InvalidationStateTracker>& |
| 153 | invalidation_state_tracker, |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 154 | const std::string& client_info) |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 155 | : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 156 | core_( |
| 157 | new Core(browser_sync::MakeWeakHandle( |
| 158 | weak_ptr_factory_.GetWeakPtr()))), |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 159 | parent_message_loop_proxy_( |
[email protected] | edd685f | 2011-08-15 20:33:46 | [diff] [blame] | 160 | base::MessageLoopProxy::current()), |
[email protected] | 942e202 | 2011-04-07 22:27:43 | [diff] [blame] | 161 | io_message_loop_proxy_(notifier_options.request_context_getter-> |
| 162 | GetIOMessageLoopProxy()) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 163 | if (!io_message_loop_proxy_->PostTask( |
| 164 | FROM_HERE, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 165 | base::Bind( |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 166 | &NonBlockingInvalidationNotifier::Core::Initialize, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 167 | core_.get(), |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 168 | notifier_options, |
| 169 | initial_max_invalidation_versions, |
[email protected] | 46e43ee | 2012-05-18 19:24:41 | [diff] [blame] | 170 | invalidation_state_tracker, |
[email protected] | e3b0ee5 | 2011-10-12 03:04:13 | [diff] [blame] | 171 | client_info))) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 172 | NOTREACHED(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 173 | } |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | NonBlockingInvalidationNotifier::~NonBlockingInvalidationNotifier() { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 177 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 178 | if (!io_message_loop_proxy_->PostTask( |
| 179 | FROM_HERE, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 180 | base::Bind(&NonBlockingInvalidationNotifier::Core::Teardown, |
| 181 | core_.get()))) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 182 | NOTREACHED(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 183 | } |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | void NonBlockingInvalidationNotifier::AddObserver( |
| 187 | SyncNotifierObserver* observer) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 188 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 189 | observers_.AddObserver(observer); |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | void NonBlockingInvalidationNotifier::RemoveObserver( |
| 193 | SyncNotifierObserver* observer) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 194 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 195 | observers_.RemoveObserver(observer); |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 196 | } |
| 197 | |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 198 | void 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] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 203 | base::Bind(&NonBlockingInvalidationNotifier::Core::SetUniqueId, |
| 204 | core_.get(), unique_id))) { |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 205 | NOTREACHED(); |
| 206 | } |
| 207 | } |
| 208 | |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 209 | void NonBlockingInvalidationNotifier::SetState(const std::string& state) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 210 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 211 | if (!io_message_loop_proxy_->PostTask( |
| 212 | FROM_HERE, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 213 | base::Bind(&NonBlockingInvalidationNotifier::Core::SetState, |
| 214 | core_.get(), state))) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 215 | NOTREACHED(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 216 | } |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 217 | } |
| 218 | |
| 219 | void NonBlockingInvalidationNotifier::UpdateCredentials( |
| 220 | const std::string& email, const std::string& token) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 221 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 222 | if (!io_message_loop_proxy_->PostTask( |
| 223 | FROM_HERE, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 224 | base::Bind(&NonBlockingInvalidationNotifier::Core::UpdateCredentials, |
| 225 | core_.get(), email, token))) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 226 | NOTREACHED(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 227 | } |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | void NonBlockingInvalidationNotifier::UpdateEnabledTypes( |
[email protected] | 400f521a | 2011-12-13 01:50:23 | [diff] [blame] | 231 | syncable::ModelTypeSet enabled_types) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 232 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 233 | if (!io_message_loop_proxy_->PostTask( |
| 234 | FROM_HERE, |
[email protected] | 09e170f | 2011-10-28 23:22:02 | [diff] [blame] | 235 | base::Bind(&NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes, |
| 236 | core_.get(), enabled_types))) { |
[email protected] | daf4e10 | 2011-04-26 08:30:28 | [diff] [blame] | 237 | NOTREACHED(); |
[email protected] | 0a561205 | 2011-06-29 03:29:18 | [diff] [blame] | 238 | } |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 239 | } |
| 240 | |
[email protected] | 2f15fd0e | 2011-08-27 05:29:09 | [diff] [blame] | 241 | void NonBlockingInvalidationNotifier::SendNotification( |
[email protected] | 400f521a | 2011-12-13 01:50:23 | [diff] [blame] | 242 | syncable::ModelTypeSet changed_types) { |
[email protected] | f968240 | 2011-06-28 22:34:27 | [diff] [blame] | 243 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
[email protected] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 244 | // InvalidationClient doesn't implement SendNotification(), so no |
| 245 | // need to forward on the call. |
| 246 | } |
| 247 | |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 248 | void NonBlockingInvalidationNotifier::OnIncomingNotification( |
[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 249 | const syncable::ModelTypePayloadMap& type_payloads, |
| 250 | IncomingNotificationSource source) { |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 251 | DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 252 | FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, |
[email protected] | 6990e4e0 | 2012-01-26 00:44:53 | [diff] [blame] | 253 | OnIncomingNotification(type_payloads, source)); |
[email protected] | b9908a24 | 2011-11-19 09:31:32 | [diff] [blame] | 254 | } |
| 255 | |
| 256 | void 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 | |
| 263 | void 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] | 0a80fed | 2011-03-24 22:31:48 | [diff] [blame] | 270 | } // namespace sync_notifier |