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" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "sync/notifier/sync_notifier_observer.h" | 14 #include "sync/notifier/sync_notifier_observer.h" |
15 #include "sync/protocol/service_constants.h" | |
16 #include "sync/syncable/model_type_payload_map.h" | 15 #include "sync/syncable/model_type_payload_map.h" |
17 | 16 |
18 namespace sync_notifier { | 17 namespace sync_notifier { |
19 | 18 |
20 const char* kSyncP2PNotificationChannel = "http://www.google.com/chrome/sync"; | 19 const char* kSyncP2PNotificationChannel = "http://www.google.com/chrome/sync"; |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 const char kNotifySelf[] = "notifySelf"; | 23 const char kNotifySelf[] = "notifySelf"; |
25 const char kNotifyOthers[] = "notifyOthers"; | 24 const char kNotifyOthers[] = "notifyOthers"; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 ListValue* changed_types_list = NULL; | 133 ListValue* changed_types_list = NULL; |
135 if (!data_dict->GetList(kChangedTypesKey, &changed_types_list)) { | 134 if (!data_dict->GetList(kChangedTypesKey, &changed_types_list)) { |
136 LOG(WARNING) << "Could not find list value for " | 135 LOG(WARNING) << "Could not find list value for " |
137 << kChangedTypesKey; | 136 << kChangedTypesKey; |
138 return false; | 137 return false; |
139 } | 138 } |
140 changed_types_ = syncable::ModelTypeSetFromValue(*changed_types_list); | 139 changed_types_ = syncable::ModelTypeSetFromValue(*changed_types_list); |
141 return true; | 140 return true; |
142 } | 141 } |
143 | 142 |
144 P2PNotifier::P2PNotifier(notifier::TalkMediator* talk_mediator, | 143 P2PNotifier::P2PNotifier(notifier::PushClient* push_client, |
145 P2PNotificationTarget send_notification_target) | 144 P2PNotificationTarget send_notification_target) |
146 : talk_mediator_(talk_mediator), | 145 : push_client_(push_client), |
147 logged_in_(false), | 146 logged_in_(false), |
148 notifications_enabled_(false), | 147 notifications_enabled_(false), |
149 send_notification_target_(send_notification_target), | 148 send_notification_target_(send_notification_target), |
150 parent_message_loop_proxy_( | 149 parent_message_loop_proxy_( |
151 base::MessageLoopProxy::current()) { | 150 base::MessageLoopProxy::current()) { |
152 DCHECK(send_notification_target_ == NOTIFY_OTHERS || | 151 DCHECK(send_notification_target_ == NOTIFY_OTHERS || |
153 send_notification_target_ == NOTIFY_ALL); | 152 send_notification_target_ == NOTIFY_ALL); |
154 talk_mediator_->SetDelegate(this); | 153 push_client_->AddObserver(this); |
155 } | 154 } |
156 | 155 |
157 P2PNotifier::~P2PNotifier() { | 156 P2PNotifier::~P2PNotifier() { |
158 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 157 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 158 push_client_->RemoveObserver(this); |
159 } | 159 } |
160 | 160 |
161 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { | 161 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { |
162 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 162 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
163 observer_list_.AddObserver(observer); | 163 observer_list_.AddObserver(observer); |
164 } | 164 } |
165 | 165 |
166 // Note: Since we need to shutdown TalkMediator on the method_thread, we are | |
167 // calling Logout on TalkMediator when the last observer is removed. | |
168 // Users will need to call UpdateCredentials again to use the same object. | |
169 // TODO(akalin): Think of a better solution to fix this. | |
170 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { | 166 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { |
171 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 167 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
172 observer_list_.RemoveObserver(observer); | 168 observer_list_.RemoveObserver(observer); |
173 | |
174 // Logout after the last observer is removed. | |
175 if (observer_list_.size() == 0) { | |
176 talk_mediator_->Logout(); | |
177 } | |
178 } | 169 } |
179 | 170 |
180 void P2PNotifier::SetUniqueId(const std::string& unique_id) { | 171 void P2PNotifier::SetUniqueId(const std::string& unique_id) { |
181 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 172 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
182 unique_id_ = unique_id; | 173 unique_id_ = unique_id; |
183 } | 174 } |
184 | 175 |
185 void P2PNotifier::SetState(const std::string& state) { | 176 void P2PNotifier::SetState(const std::string& state) { |
186 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 177 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
187 } | 178 } |
188 | 179 |
189 void P2PNotifier::UpdateCredentials( | 180 void P2PNotifier::UpdateCredentials( |
190 const std::string& email, const std::string& token) { | 181 const std::string& email, const std::string& token) { |
191 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 182 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
| 183 notifier::Subscription subscription; |
| 184 subscription.channel = kSyncP2PNotificationChannel; |
| 185 // There may be some subtle issues around case sensitivity of the |
| 186 // from field, but it doesn't matter too much since this is only |
| 187 // used in p2p mode (which is only used in testing). |
| 188 subscription.from = email; |
| 189 push_client_->UpdateSubscriptions( |
| 190 notifier::SubscriptionList(1, subscription)); |
| 191 |
192 // If already logged in, the new credentials will take effect on the | 192 // If already logged in, the new credentials will take effect on the |
193 // next reconnection. | 193 // next reconnection. |
194 talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME); | 194 push_client_->UpdateCredentials(email, token); |
195 if (!logged_in_) { | 195 logged_in_ = true; |
196 if (!talk_mediator_->Login()) { | |
197 LOG(DFATAL) << "Could not login for " << email; | |
198 return; | |
199 } | |
200 | |
201 notifier::Subscription subscription; | |
202 subscription.channel = kSyncP2PNotificationChannel; | |
203 // There may be some subtle issues around case sensitivity of the | |
204 // from field, but it doesn't matter too much since this is only | |
205 // used in p2p mode (which is only used in testing). | |
206 subscription.from = email; | |
207 talk_mediator_->AddSubscription(subscription); | |
208 | |
209 logged_in_ = true; | |
210 } | |
211 } | 196 } |
212 | 197 |
213 void P2PNotifier::UpdateEnabledTypes( | 198 void P2PNotifier::UpdateEnabledTypes( |
214 syncable::ModelTypeSet enabled_types) { | 199 syncable::ModelTypeSet enabled_types) { |
215 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 200 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
216 const syncable::ModelTypeSet new_enabled_types = | 201 const syncable::ModelTypeSet new_enabled_types = |
217 Difference(enabled_types, enabled_types_); | 202 Difference(enabled_types, enabled_types_); |
218 enabled_types_ = enabled_types; | 203 enabled_types_ = enabled_types; |
219 const P2PNotificationData notification_data( | 204 const P2PNotificationData notification_data( |
220 unique_id_, NOTIFY_SELF, new_enabled_types); | 205 unique_id_, NOTIFY_SELF, new_enabled_types); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 DVLOG(1) << "No changed types -- not emitting notification"; | 259 DVLOG(1) << "No changed types -- not emitting notification"; |
275 return; | 260 return; |
276 } | 261 } |
277 const syncable::ModelTypePayloadMap& type_payloads = | 262 const syncable::ModelTypePayloadMap& type_payloads = |
278 syncable::ModelTypePayloadMapFromEnumSet( | 263 syncable::ModelTypePayloadMapFromEnumSet( |
279 notification_data.GetChangedTypes(), std::string()); | 264 notification_data.GetChangedTypes(), std::string()); |
280 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, | 265 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, |
281 OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); | 266 OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); |
282 } | 267 } |
283 | 268 |
284 void P2PNotifier::OnOutgoingNotification() {} | |
285 | |
286 void P2PNotifier::SendNotificationDataForTest( | 269 void P2PNotifier::SendNotificationDataForTest( |
287 const P2PNotificationData& notification_data) { | 270 const P2PNotificationData& notification_data) { |
288 SendNotificationData(notification_data); | 271 SendNotificationData(notification_data); |
289 } | 272 } |
290 | 273 |
291 void P2PNotifier::SendNotificationData( | 274 void P2PNotifier::SendNotificationData( |
292 const P2PNotificationData& notification_data) { | 275 const P2PNotificationData& notification_data) { |
293 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); | 276 DCHECK(parent_message_loop_proxy_->BelongsToCurrentThread()); |
294 notifier::Notification notification; | 277 notifier::Notification notification; |
295 notification.channel = kSyncP2PNotificationChannel; | 278 notification.channel = kSyncP2PNotificationChannel; |
296 notification.data = notification_data.ToString(); | 279 notification.data = notification_data.ToString(); |
297 DVLOG(1) << "Sending XMPP notification: " << notification.ToString(); | 280 DVLOG(1) << "Sending XMPP notification: " << notification.ToString(); |
298 talk_mediator_->SendNotification(notification); | 281 push_client_->SendNotification(notification); |
299 } | 282 } |
300 | 283 |
301 } // namespace sync_notifier | 284 } // namespace sync_notifier |
OLD | NEW |