Home | History | Annotate | Download | only in host
      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