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