1 // Copyright (c) 2012 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/jingle_glue/fake_signal_strategy.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/stl_util.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "base/thread_task_runner_handle.h" 14 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 15 #include "third_party/libjingle/source/talk/xmpp/constants.h" 16 17 namespace remoting { 18 19 // static 20 void FakeSignalStrategy::Connect(FakeSignalStrategy* peer1, 21 FakeSignalStrategy* peer2) { 22 peer1->peer_ = peer2; 23 peer2->peer_ = peer1; 24 } 25 26 FakeSignalStrategy::FakeSignalStrategy(const std::string& jid) 27 : jid_(jid), 28 peer_(NULL), 29 last_id_(0), 30 weak_factory_(this) { 31 32 } 33 34 FakeSignalStrategy::~FakeSignalStrategy() { 35 while (!received_messages_.empty()) { 36 delete received_messages_.front(); 37 received_messages_.pop_front(); 38 } 39 } 40 41 void FakeSignalStrategy::Connect() { 42 DCHECK(CalledOnValidThread()); 43 FOR_EACH_OBSERVER(Listener, listeners_, 44 OnSignalStrategyStateChange(CONNECTED)); 45 } 46 47 void FakeSignalStrategy::Disconnect() { 48 DCHECK(CalledOnValidThread()); 49 FOR_EACH_OBSERVER(Listener, listeners_, 50 OnSignalStrategyStateChange(DISCONNECTED)); 51 } 52 53 SignalStrategy::State FakeSignalStrategy::GetState() const { 54 return CONNECTED; 55 } 56 57 SignalStrategy::Error FakeSignalStrategy::GetError() const { 58 return OK; 59 } 60 61 std::string FakeSignalStrategy::GetLocalJid() const { 62 DCHECK(CalledOnValidThread()); 63 return jid_; 64 } 65 66 void FakeSignalStrategy::AddListener(Listener* listener) { 67 DCHECK(CalledOnValidThread()); 68 listeners_.AddObserver(listener); 69 } 70 71 void FakeSignalStrategy::RemoveListener(Listener* listener) { 72 DCHECK(CalledOnValidThread()); 73 listeners_.RemoveObserver(listener); 74 } 75 76 bool FakeSignalStrategy::SendStanza(scoped_ptr<buzz::XmlElement> stanza) { 77 DCHECK(CalledOnValidThread()); 78 79 stanza->SetAttr(buzz::QN_FROM, jid_); 80 81 if (peer_) { 82 peer_->OnIncomingMessage(stanza.Pass()); 83 return true; 84 } else { 85 return false; 86 } 87 } 88 89 std::string FakeSignalStrategy::GetNextId() { 90 ++last_id_; 91 return base::IntToString(last_id_); 92 } 93 94 void FakeSignalStrategy::OnIncomingMessage( 95 scoped_ptr<buzz::XmlElement> stanza) { 96 pending_messages_.push(stanza.get()); 97 received_messages_.push_back(stanza.release()); 98 base::ThreadTaskRunnerHandle::Get()->PostTask( 99 FROM_HERE, base::Bind(&FakeSignalStrategy::DeliverIncomingMessages, 100 weak_factory_.GetWeakPtr())); 101 } 102 103 void FakeSignalStrategy::DeliverIncomingMessages() { 104 while (!pending_messages_.empty()) { 105 buzz::XmlElement* stanza = pending_messages_.front(); 106 const std::string& to_field = stanza->Attr(buzz::QN_TO); 107 if (to_field != jid_) { 108 LOG(WARNING) << "Dropping stanza that is addressed to " << to_field 109 << ". Local jid: " << jid_ 110 << ". Message content: " << stanza->Str(); 111 return; 112 } 113 114 ObserverListBase<Listener>::Iterator it(listeners_); 115 Listener* listener; 116 while ((listener = it.GetNext()) != NULL) { 117 if (listener->OnSignalStrategyIncomingStanza(stanza)) 118 break; 119 } 120 121 pending_messages_.pop(); 122 } 123 } 124 125 } // namespace remoting 126