OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "sync/notifier/p2p_notifier.h" | 5 #include "sync/notifier/p2p_notifier.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/message_loop_proxy.h" | |
13 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "jingle/notifier/listener/push_client.h" |
14 #include "sync/notifier/sync_notifier_observer.h" | 14 #include "sync/notifier/sync_notifier_observer.h" |
15 #include "sync/syncable/model_type_payload_map.h" | 15 #include "sync/syncable/model_type_payload_map.h" |
16 | 16 |
17 namespace sync_notifier { | 17 namespace sync_notifier { |
18 | 18 |
19 const char* kSyncP2PNotificationChannel = "http://www.google.com/chrome/sync"; | 19 const char* kSyncP2PNotificationChannel = "http://www.google.com/chrome/sync"; |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 const char kNotifySelf[] = "notifySelf"; | 23 const char kNotifySelf[] = "notifySelf"; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 ListValue* changed_types_list = NULL; | 133 ListValue* changed_types_list = NULL; |
134 if (!data_dict->GetList(kChangedTypesKey, &changed_types_list)) { | 134 if (!data_dict->GetList(kChangedTypesKey, &changed_types_list)) { |
135 LOG(WARNING) << "Could not find list value for " | 135 LOG(WARNING) << "Could not find list value for " |
136 << kChangedTypesKey; | 136 << kChangedTypesKey; |
137 return false; | 137 return false; |
138 } | 138 } |
139 changed_types_ = syncable::ModelTypeSetFromValue(*changed_types_list); | 139 changed_types_ = syncable::ModelTypeSetFromValue(*changed_types_list); |
140 return true; | 140 return true; |
141 } | 141 } |
142 | 142 |
143 P2PNotifier::P2PNotifier(const notifier::NotifierOptions& notifier_options, | 143 P2PNotifier::P2PNotifier(scoped_ptr<notifier::PushClient> push_client, |
144 P2PNotificationTarget send_notification_target) | 144 P2PNotificationTarget send_notification_target) |
145 : push_client_(notifier_options), | 145 : push_client_(push_client.Pass()), |
146 logged_in_(false), | 146 logged_in_(false), |
147 notifications_enabled_(false), | 147 notifications_enabled_(false), |
148 send_notification_target_(send_notification_target), | 148 send_notification_target_(send_notification_target) { |
149 parent_message_loop_proxy_(base::MessageLoopProxy::current()) { | |
150 DCHECK(send_notification_target_ == NOTIFY_OTHERS || | 149 DCHECK(send_notification_target_ == NOTIFY_OTHERS || |
151 send_notification_target_ == NOTIFY_ALL); | 150 send_notification_target_ == NOTIFY_ALL); |
152 push_client_.AddObserver(this); | 151 push_client_->AddObserver(this); |
153 } | 152 } |
154 | 153 |
155 P2PNotifier::~P2PNotifier() { | 154 P2PNotifier::~P2PNotifier() { |
156 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 155 DCHECK(non_thread_safe_.CalledOnValidThread()); |
157 push_client_.RemoveObserver(this); | 156 push_client_->RemoveObserver(this); |
158 } | 157 } |
159 | 158 |
160 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { | 159 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { |
161 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 160 DCHECK(non_thread_safe_.CalledOnValidThread()); |
162 observer_list_.AddObserver(observer); | 161 observer_list_.AddObserver(observer); |
163 } | 162 } |
164 | 163 |
165 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { | 164 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { |
166 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 165 DCHECK(non_thread_safe_.CalledOnValidThread()); |
167 observer_list_.RemoveObserver(observer); | 166 observer_list_.RemoveObserver(observer); |
168 } | 167 } |
169 | 168 |
170 void P2PNotifier::SetUniqueId(const std::string& unique_id) { | 169 void P2PNotifier::SetUniqueId(const std::string& unique_id) { |
171 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 170 DCHECK(non_thread_safe_.CalledOnValidThread()); |
172 unique_id_ = unique_id; | 171 unique_id_ = unique_id; |
173 } | 172 } |
174 | 173 |
175 void P2PNotifier::SetState(const std::string& state) { | 174 void P2PNotifier::SetState(const std::string& state) { |
176 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 175 DCHECK(non_thread_safe_.CalledOnValidThread()); |
| 176 // Do nothing. |
177 } | 177 } |
178 | 178 |
179 void P2PNotifier::UpdateCredentials( | 179 void P2PNotifier::UpdateCredentials( |
180 const std::string& email, const std::string& token) { | 180 const std::string& email, const std::string& token) { |
181 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 181 DCHECK(non_thread_safe_.CalledOnValidThread()); |
182 notifier::Subscription subscription; | 182 notifier::Subscription subscription; |
183 subscription.channel = kSyncP2PNotificationChannel; | 183 subscription.channel = kSyncP2PNotificationChannel; |
184 // There may be some subtle issues around case sensitivity of the | 184 // There may be some subtle issues around case sensitivity of the |
185 // from field, but it doesn't matter too much since this is only | 185 // from field, but it doesn't matter too much since this is only |
186 // used in p2p mode (which is only used in testing). | 186 // used in p2p mode (which is only used in testing). |
187 subscription.from = email; | 187 subscription.from = email; |
188 push_client_.UpdateSubscriptions( | 188 push_client_->UpdateSubscriptions( |
189 notifier::SubscriptionList(1, subscription)); | 189 notifier::SubscriptionList(1, subscription)); |
190 | |
191 // If already logged in, the new credentials will take effect on the | 190 // If already logged in, the new credentials will take effect on the |
192 // next reconnection. | 191 // next reconnection. |
193 push_client_.UpdateCredentials(email, token); | 192 push_client_->UpdateCredentials(email, token); |
194 logged_in_ = true; | 193 logged_in_ = true; |
195 } | 194 } |
196 | 195 |
197 void P2PNotifier::UpdateEnabledTypes( | 196 void P2PNotifier::UpdateEnabledTypes( |
198 syncable::ModelTypeSet enabled_types) { | 197 syncable::ModelTypeSet enabled_types) { |
199 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 198 DCHECK(non_thread_safe_.CalledOnValidThread()); |
200 const syncable::ModelTypeSet new_enabled_types = | 199 const syncable::ModelTypeSet new_enabled_types = |
201 Difference(enabled_types, enabled_types_); | 200 Difference(enabled_types, enabled_types_); |
202 enabled_types_ = enabled_types; | 201 enabled_types_ = enabled_types; |
203 const P2PNotificationData notification_data( | 202 const P2PNotificationData notification_data( |
204 unique_id_, NOTIFY_SELF, new_enabled_types); | 203 unique_id_, NOTIFY_SELF, new_enabled_types); |
205 SendNotificationData(notification_data); | 204 SendNotificationData(notification_data); |
206 } | 205 } |
207 | 206 |
208 void P2PNotifier::SendNotification( | 207 void P2PNotifier::SendNotification( |
209 syncable::ModelTypeSet changed_types) { | 208 syncable::ModelTypeSet changed_types) { |
210 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 209 DCHECK(non_thread_safe_.CalledOnValidThread()); |
211 const P2PNotificationData notification_data( | 210 const P2PNotificationData notification_data( |
212 unique_id_, send_notification_target_, changed_types); | 211 unique_id_, send_notification_target_, changed_types); |
213 SendNotificationData(notification_data); | 212 SendNotificationData(notification_data); |
214 } | 213 } |
215 | 214 |
216 void P2PNotifier::OnNotificationStateChange(bool notifications_enabled) { | 215 void P2PNotifier::OnNotificationStateChange(bool notifications_enabled) { |
217 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 216 DCHECK(non_thread_safe_.CalledOnValidThread()); |
218 bool disabled_to_enabled = notifications_enabled && !notifications_enabled_; | 217 bool disabled_to_enabled = notifications_enabled && !notifications_enabled_; |
219 notifications_enabled_ = notifications_enabled; | 218 notifications_enabled_ = notifications_enabled; |
220 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, | 219 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, |
221 OnNotificationStateChange(notifications_enabled_)); | 220 OnNotificationStateChange(notifications_enabled_)); |
222 if (disabled_to_enabled) { | 221 if (disabled_to_enabled) { |
223 const P2PNotificationData notification_data( | 222 const P2PNotificationData notification_data( |
224 unique_id_, NOTIFY_SELF, enabled_types_); | 223 unique_id_, NOTIFY_SELF, enabled_types_); |
225 SendNotificationData(notification_data); | 224 SendNotificationData(notification_data); |
226 } | 225 } |
227 } | 226 } |
228 | 227 |
229 void P2PNotifier::OnIncomingNotification( | 228 void P2PNotifier::OnIncomingNotification( |
230 const notifier::Notification& notification) { | 229 const notifier::Notification& notification) { |
231 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 230 DCHECK(non_thread_safe_.CalledOnValidThread()); |
232 DVLOG(1) << "Received notification " << notification.ToString(); | 231 DVLOG(1) << "Received notification " << notification.ToString(); |
233 if (!logged_in_) { | 232 if (!logged_in_) { |
234 DVLOG(1) << "Not logged in yet -- not emitting notification"; | 233 DVLOG(1) << "Not logged in yet -- not emitting notification"; |
235 return; | 234 return; |
236 } | 235 } |
237 if (!notifications_enabled_) { | 236 if (!notifications_enabled_) { |
238 DVLOG(1) << "Notifications not enabled -- not emitting notification"; | 237 DVLOG(1) << "Notifications not enabled -- not emitting notification"; |
239 return; | 238 return; |
240 } | 239 } |
241 if (notification.channel != kSyncP2PNotificationChannel) { | 240 if (notification.channel != kSyncP2PNotificationChannel) { |
(...skipping 16 matching lines...) Expand all Loading... |
258 DVLOG(1) << "No changed types -- not emitting notification"; | 257 DVLOG(1) << "No changed types -- not emitting notification"; |
259 return; | 258 return; |
260 } | 259 } |
261 const syncable::ModelTypePayloadMap& type_payloads = | 260 const syncable::ModelTypePayloadMap& type_payloads = |
262 syncable::ModelTypePayloadMapFromEnumSet( | 261 syncable::ModelTypePayloadMapFromEnumSet( |
263 notification_data.GetChangedTypes(), std::string()); | 262 notification_data.GetChangedTypes(), std::string()); |
264 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, | 263 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, |
265 OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); | 264 OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); |
266 } | 265 } |
267 | 266 |
268 void P2PNotifier::SimulateConnectForTest( | |
269 base::WeakPtr<buzz::XmppTaskParentInterface> base_task) { | |
270 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | |
271 push_client_.SimulateConnectAndSubscribeForTest(base_task); | |
272 } | |
273 | |
274 void P2PNotifier::ReflectSentNotificationsForTest() { | |
275 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | |
276 push_client_.ReflectSentNotificationsForTest(); | |
277 } | |
278 | |
279 void P2PNotifier::SendNotificationDataForTest( | 267 void P2PNotifier::SendNotificationDataForTest( |
280 const P2PNotificationData& notification_data) { | 268 const P2PNotificationData& notification_data) { |
281 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 269 DCHECK(non_thread_safe_.CalledOnValidThread()); |
282 SendNotificationData(notification_data); | 270 SendNotificationData(notification_data); |
283 } | 271 } |
284 | 272 |
285 void P2PNotifier::SendNotificationData( | 273 void P2PNotifier::SendNotificationData( |
286 const P2PNotificationData& notification_data) { | 274 const P2PNotificationData& notification_data) { |
287 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 275 DCHECK(non_thread_safe_.CalledOnValidThread()); |
288 notifier::Notification notification; | 276 notifier::Notification notification; |
289 notification.channel = kSyncP2PNotificationChannel; | 277 notification.channel = kSyncP2PNotificationChannel; |
290 notification.data = notification_data.ToString(); | 278 notification.data = notification_data.ToString(); |
291 DVLOG(1) << "Sending XMPP notification: " << notification.ToString(); | 279 DVLOG(1) << "Sending XMPP notification: " << notification.ToString(); |
292 push_client_.SendNotification(notification); | 280 push_client_->SendNotification(notification); |
293 } | 281 } |
294 | 282 |
295 } // namespace sync_notifier | 283 } // namespace sync_notifier |
OLD | NEW |