fake_signal_strategy.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Copyright 2014 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. #include "remoting/signaling/fake_signal_strategy.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/location.h"
  8. #include "base/logging.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "base/task/single_thread_task_runner.h"
  11. #include "base/threading/thread_task_runner_handle.h"
  12. #include "remoting/signaling/signaling_id_util.h"
  13. #include "remoting/signaling/xmpp_constants.h"
  14. #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
  15. namespace remoting {
  16. // static
  17. void FakeSignalStrategy::Connect(FakeSignalStrategy* peer1,
  18. FakeSignalStrategy* peer2) {
  19. DCHECK(peer1->main_thread_->BelongsToCurrentThread());
  20. DCHECK(peer2->main_thread_->BelongsToCurrentThread());
  21. peer1->ConnectTo(peer2);
  22. peer2->ConnectTo(peer1);
  23. }
  24. FakeSignalStrategy::FakeSignalStrategy(const SignalingAddress& address)
  25. : main_thread_(base::ThreadTaskRunnerHandle::Get()),
  26. address_(address),
  27. last_id_(0) {
  28. DETACH_FROM_SEQUENCE(sequence_checker_);
  29. }
  30. FakeSignalStrategy::~FakeSignalStrategy() {
  31. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  32. }
  33. void FakeSignalStrategy::SetError(Error error) {
  34. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  35. error_ = error;
  36. }
  37. void FakeSignalStrategy::SetIsSignInError(bool is_sign_in_error) {
  38. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  39. is_sign_in_error_ = is_sign_in_error;
  40. }
  41. void FakeSignalStrategy::SetState(State state) {
  42. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  43. if (state == state_) {
  44. return;
  45. }
  46. state_ = state;
  47. for (auto& observer : listeners_)
  48. observer.OnSignalStrategyStateChange(state_);
  49. }
  50. void FakeSignalStrategy::SetPeerCallback(const PeerCallback& peer_callback) {
  51. peer_callback_ = peer_callback;
  52. }
  53. void FakeSignalStrategy::ConnectTo(FakeSignalStrategy* peer) {
  54. PeerCallback peer_callback =
  55. base::BindRepeating(&FakeSignalStrategy::DeliverMessageOnThread,
  56. main_thread_, weak_factory_.GetWeakPtr());
  57. if (peer->main_thread_->BelongsToCurrentThread()) {
  58. peer->SetPeerCallback(std::move(peer_callback));
  59. } else {
  60. peer->main_thread_->PostTask(
  61. FROM_HERE,
  62. base::BindOnce(&FakeSignalStrategy::SetPeerCallback,
  63. base::Unretained(peer), std::move(peer_callback)));
  64. }
  65. }
  66. void FakeSignalStrategy::SetLocalAddress(const SignalingAddress& address) {
  67. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  68. address_ = address;
  69. }
  70. void FakeSignalStrategy::SimulateMessageReordering() {
  71. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  72. simulate_reorder_ = true;
  73. }
  74. void FakeSignalStrategy::SimulateTwoStageConnect() {
  75. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  76. simulate_two_stage_connect_ = true;
  77. }
  78. void FakeSignalStrategy::OnIncomingMessage(
  79. std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
  80. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  81. if (!simulate_reorder_) {
  82. NotifyListeners(std::move(stanza));
  83. return;
  84. }
  85. // Simulate IQ messages re-ordering by swapping the delivery order of
  86. // next pair of messages.
  87. if (pending_stanza_) {
  88. NotifyListeners(std::move(stanza));
  89. NotifyListeners(std::move(pending_stanza_));
  90. pending_stanza_.reset();
  91. } else {
  92. pending_stanza_ = std::move(stanza);
  93. }
  94. }
  95. void FakeSignalStrategy::ProceedConnect() {
  96. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  97. SetState(CONNECTED);
  98. }
  99. void FakeSignalStrategy::Connect() {
  100. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  101. SetState(simulate_two_stage_connect_ ? CONNECTING : CONNECTED);
  102. }
  103. void FakeSignalStrategy::Disconnect() {
  104. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  105. SetState(DISCONNECTED);
  106. }
  107. SignalStrategy::State FakeSignalStrategy::GetState() const {
  108. return state_;
  109. }
  110. SignalStrategy::Error FakeSignalStrategy::GetError() const {
  111. return error_;
  112. }
  113. const SignalingAddress& FakeSignalStrategy::GetLocalAddress() const {
  114. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  115. return address_;
  116. }
  117. void FakeSignalStrategy::AddListener(Listener* listener) {
  118. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  119. listeners_.AddObserver(listener);
  120. }
  121. void FakeSignalStrategy::RemoveListener(Listener* listener) {
  122. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  123. listeners_.RemoveObserver(listener);
  124. }
  125. bool FakeSignalStrategy::SendStanza(std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
  126. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  127. address_.SetInMessage(stanza.get(), SignalingAddress::FROM);
  128. if (peer_callback_.is_null())
  129. return false;
  130. if (send_delay_.is_zero()) {
  131. peer_callback_.Run(std::move(stanza));
  132. } else {
  133. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  134. FROM_HERE, base::BindOnce(peer_callback_, std::move(stanza)),
  135. send_delay_);
  136. }
  137. return true;
  138. }
  139. bool FakeSignalStrategy::SendMessage(
  140. const SignalingAddress& destination_address,
  141. const ftl::ChromotingMessage& message) {
  142. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  143. NOTIMPLEMENTED();
  144. return false;
  145. }
  146. std::string FakeSignalStrategy::GetNextId() {
  147. ++last_id_;
  148. return base::NumberToString(last_id_);
  149. }
  150. bool FakeSignalStrategy::IsSignInError() const {
  151. return is_sign_in_error_;
  152. }
  153. // static
  154. void FakeSignalStrategy::DeliverMessageOnThread(
  155. scoped_refptr<base::SingleThreadTaskRunner> thread,
  156. base::WeakPtr<FakeSignalStrategy> target,
  157. std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
  158. thread->PostTask(
  159. FROM_HERE, base::BindOnce(&FakeSignalStrategy::OnIncomingMessage, target,
  160. std::move(stanza)));
  161. }
  162. void FakeSignalStrategy::NotifyListeners(
  163. std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
  164. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  165. jingle_xmpp::XmlElement* stanza_ptr = stanza.get();
  166. received_messages_.push_back(std::move(stanza));
  167. std::string to_error;
  168. SignalingAddress to =
  169. SignalingAddress::Parse(stanza_ptr, SignalingAddress::TO, &to_error);
  170. if (to != address_) {
  171. LOG(WARNING) << "Dropping stanza that is addressed to " << to.id()
  172. << ". Local address: " << address_.id()
  173. << ". Message content: " << stanza_ptr->Str();
  174. return;
  175. }
  176. for (auto& listener : listeners_) {
  177. if (listener.OnSignalStrategyIncomingStanza(stanza_ptr))
  178. break;
  179. }
  180. }
  181. } // namespace remoting