media_remoter_unittest.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright 2018 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 "components/mirroring/service/media_remoter.h"
  5. #include "base/run_loop.h"
  6. #include "base/test/mock_callback.h"
  7. #include "base/test/task_environment.h"
  8. #include "base/time/default_tick_clock.h"
  9. #include "components/mirroring/service/message_dispatcher.h"
  10. #include "components/mirroring/service/mirror_settings.h"
  11. #include "media/cast/cast_environment.h"
  12. #include "mojo/public/cpp/bindings/pending_receiver.h"
  13. #include "mojo/public/cpp/bindings/pending_remote.h"
  14. #include "testing/gmock/include/gmock/gmock.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. using ::testing::InvokeWithoutArgs;
  17. using ::testing::_;
  18. using ::testing::Mock;
  19. using media::mojom::RemotingSinkMetadata;
  20. using media::mojom::RemotingStopReason;
  21. using media::cast::RtpPayloadType;
  22. using media::cast::Codec;
  23. namespace mirroring {
  24. namespace {
  25. class MockRemotingSource final : public media::mojom::RemotingSource {
  26. public:
  27. MockRemotingSource() = default;
  28. ~MockRemotingSource() override = default;
  29. void Bind(mojo::PendingReceiver<media::mojom::RemotingSource> receiver) {
  30. receiver_.Bind(std::move(receiver));
  31. }
  32. MOCK_METHOD0(OnSinkGone, void());
  33. MOCK_METHOD0(OnStarted, void());
  34. MOCK_METHOD1(OnStartFailed, void(media::mojom::RemotingStartFailReason));
  35. MOCK_METHOD1(OnMessageFromSink, void(const std::vector<uint8_t>&));
  36. MOCK_METHOD1(OnStopped, void(RemotingStopReason));
  37. MOCK_METHOD1(OnSinkAvailable, void(const RemotingSinkMetadata&));
  38. void OnSinkAvailable(
  39. media::mojom::RemotingSinkMetadataPtr metadata) override {
  40. OnSinkAvailable(*metadata);
  41. }
  42. private:
  43. mojo::Receiver<media::mojom::RemotingSource> receiver_{this};
  44. };
  45. RemotingSinkMetadata DefaultSinkMetadata() {
  46. RemotingSinkMetadata metadata;
  47. metadata.features.push_back(media::mojom::RemotingSinkFeature::RENDERING);
  48. metadata.video_capabilities.push_back(
  49. media::mojom::RemotingSinkVideoCapability::CODEC_VP8);
  50. metadata.audio_capabilities.push_back(
  51. media::mojom::RemotingSinkAudioCapability::CODEC_BASELINE_SET);
  52. metadata.friendly_name = "Test";
  53. return metadata;
  54. }
  55. } // namespace
  56. class MediaRemoterTest : public mojom::CastMessageChannel,
  57. public MediaRemoter::Client,
  58. public ::testing::Test {
  59. public:
  60. MediaRemoterTest()
  61. : message_dispatcher_(receiver_.BindNewPipeAndPassRemote(),
  62. inbound_channel_.BindNewPipeAndPassReceiver(),
  63. error_callback_.Get()),
  64. sink_metadata_(DefaultSinkMetadata()) {}
  65. MediaRemoterTest(const MediaRemoterTest&) = delete;
  66. MediaRemoterTest& operator=(const MediaRemoterTest&) = delete;
  67. ~MediaRemoterTest() override { task_environment_.RunUntilIdle(); }
  68. protected:
  69. MOCK_METHOD1(Send, void(mojom::CastMessagePtr));
  70. MOCK_METHOD0(OnConnectToRemotingSource, void());
  71. MOCK_METHOD0(RequestRemotingStreaming, void());
  72. MOCK_METHOD0(RestartMirroringStreaming, void());
  73. // MediaRemoter::Client implementation.
  74. void ConnectToRemotingSource(
  75. mojo::PendingRemote<media::mojom::Remoter> remoter,
  76. mojo::PendingReceiver<media::mojom::RemotingSource> source_receiver)
  77. override {
  78. remoter_.Bind(std::move(remoter));
  79. remoting_source_.Bind(std::move(source_receiver));
  80. OnConnectToRemotingSource();
  81. }
  82. void CreateRemoter() {
  83. EXPECT_FALSE(media_remoter_);
  84. EXPECT_CALL(*this, OnConnectToRemotingSource()).Times(1);
  85. EXPECT_CALL(remoting_source_, OnSinkAvailable(_)).Times(1);
  86. media_remoter_ = std::make_unique<MediaRemoter>(this, sink_metadata_,
  87. &message_dispatcher_);
  88. task_environment_.RunUntilIdle();
  89. Mock::VerifyAndClear(this);
  90. Mock::VerifyAndClear(&remoting_source_);
  91. }
  92. // Requests to start a remoting session.
  93. void StartRemoting() {
  94. ASSERT_TRUE(remoter_);
  95. EXPECT_CALL(*this, RequestRemotingStreaming()).Times(1);
  96. remoter_->Start();
  97. task_environment_.RunUntilIdle();
  98. Mock::VerifyAndClear(this);
  99. }
  100. // Stops the current remoting session.
  101. void StopRemoting() {
  102. ASSERT_TRUE(remoter_);
  103. EXPECT_CALL(remoting_source_, OnStopped(RemotingStopReason::USER_DISABLED))
  104. .Times(1);
  105. EXPECT_CALL(remoting_source_, OnSinkGone()).Times(1);
  106. EXPECT_CALL(*this, RestartMirroringStreaming()).Times(1);
  107. remoter_->Stop(media::mojom::RemotingStopReason::USER_DISABLED);
  108. task_environment_.RunUntilIdle();
  109. Mock::VerifyAndClear(this);
  110. Mock::VerifyAndClear(&remoting_source_);
  111. }
  112. // Signals that a remoting streaming session starts successfully.
  113. void RemotingStreamingStarted() {
  114. ASSERT_TRUE(media_remoter_);
  115. scoped_refptr<media::cast::CastEnvironment> cast_environment =
  116. new media::cast::CastEnvironment(
  117. base::DefaultTickClock::GetInstance(),
  118. task_environment_.GetMainThreadTaskRunner(),
  119. task_environment_.GetMainThreadTaskRunner(),
  120. task_environment_.GetMainThreadTaskRunner());
  121. EXPECT_CALL(remoting_source_, OnStarted()).Times(1);
  122. media_remoter_->StartRpcMessaging(
  123. cast_environment, nullptr, media::cast::FrameSenderConfig(),
  124. MirrorSettings::GetDefaultVideoConfig(RtpPayloadType::REMOTE_VIDEO,
  125. Codec::CODEC_VIDEO_REMOTE));
  126. task_environment_.RunUntilIdle();
  127. Mock::VerifyAndClear(&remoting_source_);
  128. }
  129. // Signals that mirroring is resumed successfully.
  130. void MirroringResumed() {
  131. EXPECT_CALL(remoting_source_, OnSinkAvailable(_)).Times(1);
  132. media_remoter_->OnMirroringResumed();
  133. task_environment_.RunUntilIdle();
  134. Mock::VerifyAndClear(&remoting_source_);
  135. }
  136. // Signals that remoting session failed to start.
  137. void RemotingStartFailed() {
  138. ASSERT_TRUE(media_remoter_);
  139. EXPECT_CALL(remoting_source_, OnStartFailed(_)).Times(1);
  140. EXPECT_CALL(remoting_source_, OnSinkGone()).Times(1);
  141. EXPECT_CALL(*this, RestartMirroringStreaming()).Times(1);
  142. media_remoter_->OnRemotingFailed();
  143. task_environment_.RunUntilIdle();
  144. Mock::VerifyAndClear(this);
  145. Mock::VerifyAndClear(&remoting_source_);
  146. }
  147. private:
  148. base::test::TaskEnvironment task_environment_;
  149. mojo::Receiver<mojom::CastMessageChannel> receiver_{this};
  150. base::MockCallback<MessageDispatcher::ErrorCallback> error_callback_;
  151. mojo::Remote<mojom::CastMessageChannel> inbound_channel_;
  152. MessageDispatcher message_dispatcher_;
  153. const media::mojom::RemotingSinkMetadata sink_metadata_;
  154. MockRemotingSource remoting_source_;
  155. mojo::Remote<media::mojom::Remoter> remoter_;
  156. std::unique_ptr<MediaRemoter> media_remoter_;
  157. };
  158. TEST_F(MediaRemoterTest, StartAndStopRemoting) {
  159. CreateRemoter();
  160. StartRemoting();
  161. RemotingStreamingStarted();
  162. StopRemoting();
  163. }
  164. TEST_F(MediaRemoterTest, StopRemotingWhileStarting) {
  165. CreateRemoter();
  166. // Starts a remoting session.
  167. StartRemoting();
  168. // Immediately stops the remoting session while not started yet.
  169. StopRemoting();
  170. // Signals that successfully switch to mirroring.
  171. MirroringResumed();
  172. // Now remoting can be started again.
  173. StartRemoting();
  174. }
  175. TEST_F(MediaRemoterTest, RemotingStartFailed) {
  176. CreateRemoter();
  177. StartRemoting();
  178. RemotingStartFailed();
  179. }
  180. TEST_F(MediaRemoterTest, SwitchBetweenMultipleSessions) {
  181. CreateRemoter();
  182. // Start a remoting session.
  183. StartRemoting();
  184. RemotingStreamingStarted();
  185. // Stop the remoting session and switch to mirroring.
  186. StopRemoting();
  187. MirroringResumed();
  188. // Switch to remoting again.
  189. StartRemoting();
  190. RemotingStreamingStarted();
  191. // Switch to mirroring again.
  192. StopRemoting();
  193. MirroringResumed();
  194. }
  195. } // namespace mirroring