Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / remoting / host / host_change_notification_listener.cc
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/xmllite/xmlelement.h"
15 #include "third_party/libjingle/source/talk/xmpp/constants.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