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/p2p_notifier.h" | 5 #include "chrome/browser/sync/notifier/p2p_notifier.h" |
6 | 6 |
7 #include "chrome/browser/sync/notifier/sync_notifier_observer.h" | 7 #include "chrome/browser/sync/notifier/sync_notifier_observer.h" |
8 #include "chrome/browser/sync/protocol/service_constants.h" | 8 #include "chrome/browser/sync/protocol/service_constants.h" |
9 #include "chrome/browser/sync/syncable/model_type_payload_map.h" | 9 #include "chrome/browser/sync/syncable/model_type_payload_map.h" |
10 #include "jingle/notifier/listener/mediator_thread_impl.h" | 10 #include "jingle/notifier/listener/mediator_thread_impl.h" |
11 #include "jingle/notifier/listener/talk_mediator_impl.h" | 11 #include "jingle/notifier/listener/talk_mediator_impl.h" |
12 | 12 |
13 namespace sync_notifier { | 13 namespace sync_notifier { |
14 | 14 |
15 namespace { | 15 namespace { |
16 const char kSyncNotificationChannel[] = "http://www.google.com/chrome/sync"; | 16 const char kSyncNotificationChannel[] = "http://www.google.com/chrome/sync"; |
17 const char kSyncNotificationData[] = "sync-ping-p2p"; | 17 const char kSyncNotificationData[] = "sync-ping-p2p"; |
18 } // namespace | 18 } // namespace |
19 | 19 |
20 P2PNotifier::P2PNotifier( | 20 P2PNotifier::P2PNotifier( |
21 const notifier::NotifierOptions& notifier_options) | 21 const notifier::NotifierOptions& notifier_options) |
22 : talk_mediator_( | 22 : talk_mediator_( |
23 new notifier::TalkMediatorImpl( | 23 new notifier::TalkMediatorImpl( |
24 new notifier::MediatorThreadImpl(notifier_options), | 24 new notifier::MediatorThreadImpl(notifier_options), |
25 notifier_options)), | 25 notifier_options)), |
26 logged_in_(false), | 26 logged_in_(false), |
27 notifications_enabled_(false) { | 27 notifications_enabled_(false), |
| 28 construction_message_loop_(MessageLoop::current()), |
| 29 method_message_loop_(NULL) { |
28 talk_mediator_->SetDelegate(this); | 30 talk_mediator_->SetDelegate(this); |
29 } | 31 } |
30 | 32 |
31 P2PNotifier::~P2PNotifier() {} | 33 P2PNotifier::~P2PNotifier() { |
| 34 DCHECK_EQ(MessageLoop::current(), construction_message_loop_); |
| 35 } |
32 | 36 |
33 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { | 37 void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { |
| 38 CheckOrSetValidThread(); |
34 observer_list_.AddObserver(observer); | 39 observer_list_.AddObserver(observer); |
35 } | 40 } |
36 | 41 |
| 42 // Note: Since we need to shutdown TalkMediator on the method_thread, we are |
| 43 // calling Logout on TalkMediator when the last observer is removed. |
| 44 // Users will need to call UpdateCredentials again to use the same object. |
| 45 // TODO(akalin): Think of a better solution to fix this. |
37 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { | 46 void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { |
| 47 CheckOrSetValidThread(); |
38 observer_list_.RemoveObserver(observer); | 48 observer_list_.RemoveObserver(observer); |
| 49 |
| 50 // Logout after the last observer is removed. |
| 51 if (observer_list_.size() == 0) { |
| 52 talk_mediator_->Logout(); |
| 53 } |
39 } | 54 } |
40 | 55 |
41 void P2PNotifier::SetState(const std::string& state) {} | 56 void P2PNotifier::SetState(const std::string& state) { |
| 57 CheckOrSetValidThread(); |
| 58 } |
42 | 59 |
43 void P2PNotifier::UpdateCredentials( | 60 void P2PNotifier::UpdateCredentials( |
44 const std::string& email, const std::string& token) { | 61 const std::string& email, const std::string& token) { |
| 62 CheckOrSetValidThread(); |
45 // If already logged in, the new credentials will take effect on the | 63 // If already logged in, the new credentials will take effect on the |
46 // next reconnection. | 64 // next reconnection. |
47 talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME); | 65 talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME); |
48 if (!logged_in_) { | 66 if (!logged_in_) { |
49 if (!talk_mediator_->Login()) { | 67 if (!talk_mediator_->Login()) { |
50 LOG(DFATAL) << "Could not login for " << email; | 68 LOG(DFATAL) << "Could not login for " << email; |
51 return; | 69 return; |
52 } | 70 } |
53 | 71 |
54 notifier::Subscription subscription; | 72 notifier::Subscription subscription; |
55 subscription.channel = kSyncNotificationChannel; | 73 subscription.channel = kSyncNotificationChannel; |
56 // There may be some subtle issues around case sensitivity of the | 74 // There may be some subtle issues around case sensitivity of the |
57 // from field, but it doesn't matter too much since this is only | 75 // from field, but it doesn't matter too much since this is only |
58 // used in p2p mode (which is only used in testing). | 76 // used in p2p mode (which is only used in testing). |
59 subscription.from = email; | 77 subscription.from = email; |
60 talk_mediator_->AddSubscription(subscription); | 78 talk_mediator_->AddSubscription(subscription); |
61 | 79 |
62 logged_in_ = true; | 80 logged_in_ = true; |
63 } | 81 } |
64 } | 82 } |
65 | 83 |
66 void P2PNotifier::UpdateEnabledTypes(const syncable::ModelTypeSet& types) { | 84 void P2PNotifier::UpdateEnabledTypes(const syncable::ModelTypeSet& types) { |
| 85 CheckOrSetValidThread(); |
67 enabled_types_ = types; | 86 enabled_types_ = types; |
68 MaybeEmitNotification(); | 87 MaybeEmitNotification(); |
69 } | 88 } |
70 | 89 |
71 void P2PNotifier::SendNotification() { | 90 void P2PNotifier::SendNotification() { |
| 91 CheckOrSetValidThread(); |
72 VLOG(1) << "Sending XMPP notification..."; | 92 VLOG(1) << "Sending XMPP notification..."; |
73 notifier::Notification notification; | 93 notifier::Notification notification; |
74 notification.channel = kSyncNotificationChannel; | 94 notification.channel = kSyncNotificationChannel; |
75 notification.data = kSyncNotificationData; | 95 notification.data = kSyncNotificationData; |
76 bool success = talk_mediator_->SendNotification(notification); | 96 bool success = talk_mediator_->SendNotification(notification); |
77 if (success) { | 97 if (success) { |
78 VLOG(1) << "Sent XMPP notification"; | 98 VLOG(1) << "Sent XMPP notification"; |
79 } else { | 99 } else { |
80 VLOG(1) << "Could not send XMPP notification"; | 100 VLOG(1) << "Could not send XMPP notification"; |
81 } | 101 } |
82 } | 102 } |
83 | 103 |
84 void P2PNotifier::OnNotificationStateChange(bool notifications_enabled) { | 104 void P2PNotifier::OnNotificationStateChange(bool notifications_enabled) { |
| 105 CheckOrSetValidThread(); |
85 notifications_enabled_ = notifications_enabled; | 106 notifications_enabled_ = notifications_enabled; |
86 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, | 107 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, |
87 OnNotificationStateChange(notifications_enabled_)); | 108 OnNotificationStateChange(notifications_enabled_)); |
88 MaybeEmitNotification(); | 109 MaybeEmitNotification(); |
89 } | 110 } |
90 | 111 |
91 void P2PNotifier::OnIncomingNotification( | 112 void P2PNotifier::OnIncomingNotification( |
92 const notifier::Notification& notification) { | 113 const notifier::Notification& notification) { |
| 114 CheckOrSetValidThread(); |
93 VLOG(1) << "Sync received P2P notification."; | 115 VLOG(1) << "Sync received P2P notification."; |
94 if (notification.channel != kSyncNotificationChannel) { | 116 if (notification.channel != kSyncNotificationChannel) { |
95 LOG(WARNING) << "Notification fron unexpected source: " | 117 LOG(WARNING) << "Notification fron unexpected source: " |
96 << notification.channel; | 118 << notification.channel; |
97 } | 119 } |
98 MaybeEmitNotification(); | 120 MaybeEmitNotification(); |
99 } | 121 } |
100 | 122 |
101 void P2PNotifier::OnOutgoingNotification() {} | 123 void P2PNotifier::OnOutgoingNotification() {} |
102 | 124 |
(...skipping 10 matching lines...) Expand all Loading... |
113 VLOG(1) << "No enabled types -- not emitting notification"; | 135 VLOG(1) << "No enabled types -- not emitting notification"; |
114 return; | 136 return; |
115 } | 137 } |
116 syncable::ModelTypePayloadMap type_payloads = | 138 syncable::ModelTypePayloadMap type_payloads = |
117 syncable::ModelTypePayloadMapFromBitSet( | 139 syncable::ModelTypePayloadMapFromBitSet( |
118 syncable::ModelTypeBitSetFromSet(enabled_types_), std::string()); | 140 syncable::ModelTypeBitSetFromSet(enabled_types_), std::string()); |
119 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, | 141 FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, |
120 OnIncomingNotification(type_payloads)); | 142 OnIncomingNotification(type_payloads)); |
121 } | 143 } |
122 | 144 |
| 145 void P2PNotifier::CheckOrSetValidThread() { |
| 146 if (method_message_loop_) { |
| 147 DCHECK_EQ(MessageLoop::current(), method_message_loop_); |
| 148 } else { |
| 149 method_message_loop_ = MessageLoop::current(); |
| 150 } |
| 151 } |
| 152 |
123 } // namespace sync_notifier | 153 } // namespace sync_notifier |
OLD | NEW |