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 17namespace remoting { 18 19// static 20void FakeSignalStrategy::Connect(FakeSignalStrategy* peer1, 21 FakeSignalStrategy* peer2) { 22 peer1->peer_ = peer2; 23 peer2->peer_ = peer1; 24} 25 26FakeSignalStrategy::FakeSignalStrategy(const std::string& jid) 27 : jid_(jid), 28 peer_(NULL), 29 last_id_(0), 30 weak_factory_(this) { 31 32} 33 34FakeSignalStrategy::~FakeSignalStrategy() { 35 while (!received_messages_.empty()) { 36 delete received_messages_.front(); 37 received_messages_.pop_front(); 38 } 39} 40 41void FakeSignalStrategy::Connect() { 42 DCHECK(CalledOnValidThread()); 43 FOR_EACH_OBSERVER(Listener, listeners_, 44 OnSignalStrategyStateChange(CONNECTED)); 45} 46 47void FakeSignalStrategy::Disconnect() { 48 DCHECK(CalledOnValidThread()); 49 FOR_EACH_OBSERVER(Listener, listeners_, 50 OnSignalStrategyStateChange(DISCONNECTED)); 51} 52 53SignalStrategy::State FakeSignalStrategy::GetState() const { 54 return CONNECTED; 55} 56 57SignalStrategy::Error FakeSignalStrategy::GetError() const { 58 return OK; 59} 60 61std::string FakeSignalStrategy::GetLocalJid() const { 62 DCHECK(CalledOnValidThread()); 63 return jid_; 64} 65 66void FakeSignalStrategy::AddListener(Listener* listener) { 67 DCHECK(CalledOnValidThread()); 68 listeners_.AddObserver(listener); 69} 70 71void FakeSignalStrategy::RemoveListener(Listener* listener) { 72 DCHECK(CalledOnValidThread()); 73 listeners_.RemoveObserver(listener); 74} 75 76bool 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 89std::string FakeSignalStrategy::GetNextId() { 90 ++last_id_; 91 return base::IntToString(last_id_); 92} 93 94void 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 103void 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