| 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 "remoting/jingle_glue/xmpp_signal_strategy.h" | 5 #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h" | 8 #include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h" |
| 9 #include "remoting/jingle_glue/jingle_thread.h" | 9 #include "remoting/jingle_glue/jingle_thread.h" |
| 10 #include "remoting/jingle_glue/xmpp_socket_adapter.h" | 10 #include "remoting/jingle_glue/xmpp_socket_adapter.h" |
| 11 #include "third_party/libjingle/source/talk/base/asyncsocket.h" | 11 #include "third_party/libjingle/source/talk/base/asyncsocket.h" |
| 12 #include "third_party/libjingle/source/talk/xmpp/prexmppauth.h" | 12 #include "third_party/libjingle/source/talk/xmpp/prexmppauth.h" |
| 13 #include "third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h" | 13 #include "third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h" |
| 14 | 14 |
| 15 namespace remoting { | 15 namespace remoting { |
| 16 | 16 |
| 17 XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, | 17 XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, |
| 18 const std::string& username, | 18 const std::string& username, |
| 19 const std::string& auth_token, | 19 const std::string& auth_token, |
| 20 const std::string& auth_token_service) | 20 const std::string& auth_token_service) |
| 21 : thread_(jingle_thread), | 21 : thread_(jingle_thread), |
| 22 username_(username), | 22 username_(username), |
| 23 auth_token_(auth_token), | 23 auth_token_(auth_token), |
| 24 auth_token_service_(auth_token_service), | 24 auth_token_service_(auth_token_service), |
| 25 xmpp_client_(NULL), | 25 xmpp_client_(NULL), |
| 26 observer_(NULL) { | 26 state_(DISCONNECTED) { |
| 27 } | 27 } |
| 28 | 28 |
| 29 XmppSignalStrategy::~XmppSignalStrategy() { | 29 XmppSignalStrategy::~XmppSignalStrategy() { |
| 30 DCHECK(listeners_.empty()); | 30 DCHECK_EQ(listeners_.size(), 0U); |
| 31 Close(); | 31 Disconnect(); |
| 32 } | 32 } |
| 33 | 33 |
| 34 void XmppSignalStrategy::Init(StatusObserver* observer) { | 34 void XmppSignalStrategy::Connect() { |
| 35 observer_ = observer; | 35 // Disconnect first if we are currently connected. |
| 36 | 36 Disconnect(); |
| 37 buzz::Jid login_jid(username_); | |
| 38 | 37 |
| 39 buzz::XmppClientSettings settings; | 38 buzz::XmppClientSettings settings; |
| 39 buzz::Jid login_jid(username_); |
| 40 settings.set_user(login_jid.node()); | 40 settings.set_user(login_jid.node()); |
| 41 settings.set_host(login_jid.domain()); | 41 settings.set_host(login_jid.domain()); |
| 42 settings.set_resource("chromoting"); | 42 settings.set_resource("chromoting"); |
| 43 settings.set_use_tls(buzz::TLS_ENABLED); | 43 settings.set_use_tls(buzz::TLS_ENABLED); |
| 44 settings.set_token_service(auth_token_service_); | 44 settings.set_token_service(auth_token_service_); |
| 45 settings.set_auth_cookie(auth_token_); | 45 settings.set_auth_cookie(auth_token_); |
| 46 settings.set_server(talk_base::SocketAddress("talk.google.com", 5222)); | 46 settings.set_server(talk_base::SocketAddress("talk.google.com", 5222)); |
| 47 | 47 |
| 48 buzz::AsyncSocket* socket = new XmppSocketAdapter(settings, false); | 48 buzz::AsyncSocket* socket = new XmppSocketAdapter(settings, false); |
| 49 | 49 |
| 50 xmpp_client_ = new buzz::XmppClient(thread_->task_pump()); | 50 xmpp_client_ = new buzz::XmppClient(thread_->task_pump()); |
| 51 xmpp_client_->Connect(settings, "", socket, CreatePreXmppAuth(settings)); | 51 xmpp_client_->Connect(settings, "", socket, CreatePreXmppAuth(settings)); |
| 52 xmpp_client_->SignalStateChange.connect( | 52 xmpp_client_->SignalStateChange.connect( |
| 53 this, &XmppSignalStrategy::OnConnectionStateChanged); | 53 this, &XmppSignalStrategy::OnConnectionStateChanged); |
| 54 xmpp_client_->engine()->AddStanzaHandler(this, buzz::XmppEngine::HL_TYPE); | 54 xmpp_client_->engine()->AddStanzaHandler(this, buzz::XmppEngine::HL_TYPE); |
| 55 xmpp_client_->Start(); | 55 xmpp_client_->Start(); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void XmppSignalStrategy::Close() { | 58 void XmppSignalStrategy::Disconnect() { |
| 59 if (xmpp_client_) { | 59 if (xmpp_client_) { |
| 60 xmpp_client_->engine()->RemoveStanzaHandler(this); | 60 xmpp_client_->engine()->RemoveStanzaHandler(this); |
| 61 | 61 |
| 62 xmpp_client_->Disconnect(); | 62 xmpp_client_->Disconnect(); |
| 63 | 63 |
| 64 // |xmpp_client_| should be set to NULL in OnConnectionStateChanged() | 64 // |xmpp_client_| should be set to NULL in OnConnectionStateChanged() |
| 65 // in response to Disconnect() call above. | 65 // in response to Disconnect() call above. |
| 66 DCHECK(xmpp_client_ == NULL); | 66 DCHECK(xmpp_client_ == NULL); |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 SignalStrategy::State XmppSignalStrategy::GetState() const { |
| 71 return state_; |
| 72 } |
| 73 |
| 74 std::string XmppSignalStrategy::GetLocalJid() const { |
| 75 return xmpp_client_->jid().Str(); |
| 76 } |
| 77 |
| 70 void XmppSignalStrategy::AddListener(Listener* listener) { | 78 void XmppSignalStrategy::AddListener(Listener* listener) { |
| 71 DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == | 79 listeners_.AddObserver(listener); |
| 72 listeners_.end()); | |
| 73 listeners_.push_back(listener); | |
| 74 } | 80 } |
| 75 | 81 |
| 76 void XmppSignalStrategy::RemoveListener(Listener* listener) { | 82 void XmppSignalStrategy::RemoveListener(Listener* listener) { |
| 77 std::vector<Listener*>::iterator it = | 83 listeners_.RemoveObserver(listener); |
| 78 std::find(listeners_.begin(), listeners_.end(), listener); | |
| 79 CHECK(it != listeners_.end()); | |
| 80 listeners_.erase(it); | |
| 81 } | 84 } |
| 82 | 85 |
| 83 bool XmppSignalStrategy::SendStanza(buzz::XmlElement* stanza) { | 86 bool XmppSignalStrategy::SendStanza(buzz::XmlElement* stanza) { |
| 84 if (!xmpp_client_) { | 87 if (!xmpp_client_) { |
| 85 LOG(INFO) << "Dropping signalling message because XMPP " | 88 LOG(INFO) << "Dropping signalling message because XMPP " |
| 86 "connection has been terminated."; | 89 "connection has been terminated."; |
| 87 delete stanza; | 90 delete stanza; |
| 88 return false; | 91 return false; |
| 89 } | 92 } |
| 90 | 93 |
| 91 buzz::XmppReturnStatus status = xmpp_client_->SendStanza(stanza); | 94 buzz::XmppReturnStatus status = xmpp_client_->SendStanza(stanza); |
| 92 return status == buzz::XMPP_RETURN_OK || status == buzz::XMPP_RETURN_PENDING; | 95 return status == buzz::XMPP_RETURN_OK || status == buzz::XMPP_RETURN_PENDING; |
| 93 } | 96 } |
| 94 | 97 |
| 95 std::string XmppSignalStrategy::GetNextId() { | 98 std::string XmppSignalStrategy::GetNextId() { |
| 96 if (!xmpp_client_) { | 99 if (!xmpp_client_) { |
| 97 // If the connection has been terminated then it doesn't matter | 100 // If the connection has been terminated then it doesn't matter |
| 98 // what Id we return. | 101 // what Id we return. |
| 99 return ""; | 102 return ""; |
| 100 } | 103 } |
| 101 return xmpp_client_->NextId(); | 104 return xmpp_client_->NextId(); |
| 102 } | 105 } |
| 103 | 106 |
| 104 bool XmppSignalStrategy::HandleStanza(const buzz::XmlElement* stanza) { | 107 bool XmppSignalStrategy::HandleStanza(const buzz::XmlElement* stanza) { |
| 105 for (std::vector<Listener*>::iterator it = listeners_.begin(); | 108 ObserverListBase<Listener>::Iterator it(listeners_); |
| 106 it != listeners_.end(); ++it) { | 109 Listener* listener; |
| 107 if ((*it)->OnIncomingStanza(stanza)) | 110 while ((listener = it.GetNext()) != NULL) { |
| 108 return true; | 111 if (listener->OnSignalStrategyIncomingStanza(stanza)) |
| 112 break; |
| 109 } | 113 } |
| 110 return false; | 114 return false; |
| 111 } | 115 } |
| 112 | 116 |
| 113 void XmppSignalStrategy::OnConnectionStateChanged( | 117 void XmppSignalStrategy::OnConnectionStateChanged( |
| 114 buzz::XmppEngine::State state) { | 118 buzz::XmppEngine::State state) { |
| 119 State new_state; |
| 120 |
| 115 switch (state) { | 121 switch (state) { |
| 116 case buzz::XmppEngine::STATE_START: | 122 case buzz::XmppEngine::STATE_START: |
| 117 observer_->OnStateChange(StatusObserver::START); | 123 return; |
| 118 break; | 124 |
| 119 case buzz::XmppEngine::STATE_OPENING: | 125 case buzz::XmppEngine::STATE_OPENING: |
| 120 observer_->OnStateChange(StatusObserver::CONNECTING); | 126 new_state = CONNECTING; |
| 121 break; | 127 break; |
| 122 case buzz::XmppEngine::STATE_OPEN: | 128 case buzz::XmppEngine::STATE_OPEN: |
| 123 observer_->OnJidChange(xmpp_client_->jid().Str()); | 129 new_state = CONNECTED; |
| 124 observer_->OnStateChange(StatusObserver::CONNECTED); | |
| 125 break; | 130 break; |
| 126 case buzz::XmppEngine::STATE_CLOSED: | 131 case buzz::XmppEngine::STATE_CLOSED: |
| 127 observer_->OnStateChange(StatusObserver::CLOSED); | |
| 128 // Client is destroyed by the TaskRunner after the client is | 132 // Client is destroyed by the TaskRunner after the client is |
| 129 // closed. Reset the pointer so we don't try to use it later. | 133 // closed. Reset the pointer so we don't try to use it later. |
| 130 xmpp_client_ = NULL; | 134 xmpp_client_ = NULL; |
| 135 new_state = DISCONNECTED; |
| 131 break; | 136 break; |
| 132 default: | 137 default: |
| 133 NOTREACHED(); | 138 NOTREACHED(); |
| 134 break; | 139 return; |
| 140 } |
| 141 |
| 142 if (state_ != new_state) { |
| 143 state_ = new_state; |
| 144 FOR_EACH_OBSERVER(Listener, listeners_, |
| 145 OnSignalStrategyStateChange(new_state)); |
| 135 } | 146 } |
| 136 } | 147 } |
| 137 | 148 |
| 138 // static | 149 // static |
| 139 buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth( | 150 buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth( |
| 140 const buzz::XmppClientSettings& settings) { | 151 const buzz::XmppClientSettings& settings) { |
| 141 buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY); | 152 buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY); |
| 142 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; | 153 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; |
| 143 if (settings.token_service() == "oauth2") { | 154 if (settings.token_service() == "oauth2") { |
| 144 mechanism = "X-OAUTH2"; | 155 mechanism = "X-OAUTH2"; |
| 145 } | 156 } |
| 146 | 157 |
| 147 return new notifier::GaiaTokenPreXmppAuth( | 158 return new notifier::GaiaTokenPreXmppAuth( |
| 148 jid.Str(), | 159 jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); |
| 149 settings.auth_cookie(), | |
| 150 settings.token_service(), | |
| 151 mechanism); | |
| 152 } | 160 } |
| 153 | 161 |
| 154 } // namespace remoting | 162 } // namespace remoting |
| OLD | NEW |