| 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 |