1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "remoting/host/host_change_notification_listener.h" 6 7 #include "base/bind.h" 8 #include "base/location.h" 9 #include "base/logging.h" 10 #include "base/single_thread_task_runner.h" 11 #include "base/thread_task_runner_handle.h" 12 #include "remoting/base/constants.h" 13 #include "remoting/protocol/jingle_messages.h" 14 #include "third_party/libjingle/source/talk/xmpp/constants.h" 15 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 16 17 using buzz::QName; 18 using buzz::XmlElement; 19 20 namespace remoting { 21 22 HostChangeNotificationListener::HostChangeNotificationListener( 23 Listener* listener, 24 const std::string& host_id, 25 SignalStrategy* signal_strategy, 26 const std::string& directory_bot_jid) 27 : listener_(listener), 28 host_id_(host_id), 29 signal_strategy_(signal_strategy), 30 directory_bot_jid_(directory_bot_jid), 31 weak_factory_(this) { 32 DCHECK(signal_strategy_); 33 34 signal_strategy_->AddListener(this); 35 } 36 37 HostChangeNotificationListener::~HostChangeNotificationListener() { 38 signal_strategy_->RemoveListener(this); 39 } 40 41 void HostChangeNotificationListener::OnSignalStrategyStateChange( 42 SignalStrategy::State state) { 43 } 44 45 bool HostChangeNotificationListener::OnSignalStrategyIncomingStanza( 46 const buzz::XmlElement* stanza) { 47 if (stanza->Name() != buzz::QN_IQ || stanza->Attr(buzz::QN_TYPE) != "set") 48 return false; 49 50 const XmlElement* host_changed_element = 51 stanza->FirstNamed(QName(kChromotingXmlNamespace, "host-changed")); 52 if (!host_changed_element) 53 return false; 54 55 const std::string& host_id = 56 host_changed_element->Attr(QName(kChromotingXmlNamespace, "hostid")); 57 const std::string& from = stanza->Attr(buzz::QN_FROM); 58 const std::string& to = stanza->Attr(buzz::QN_TO); 59 if (host_id == host_id_ && from == directory_bot_jid_ && 60 to == signal_strategy_->GetLocalJid()) { 61 const std::string& operation = 62 host_changed_element->Attr(QName(kChromotingXmlNamespace, "operation")); 63 if (operation == "delete") { 64 // OnHostDeleted() may want delete |signal_strategy_|, but SignalStrategy 65 // objects cannot be deleted from a Listener callback, so OnHostDeleted() 66 // has to be invoked later. 67 base::ThreadTaskRunnerHandle::Get()->PostTask( 68 FROM_HERE, base::Bind(&HostChangeNotificationListener::OnHostDeleted, 69 weak_factory_.GetWeakPtr())); 70 } 71 } else { 72 LOG(ERROR) << "Invalid host-changed message received: " << stanza->Str(); 73 } 74 return true; 75 } 76 77 void HostChangeNotificationListener::OnHostDeleted() { 78 listener_->OnHostDeleted(); 79 } 80 81 } // namespace remoting 82