blob: 950719538cefabed4afcaa853eecb62ae4ee9215 [file] [log] [blame]
miu9f7788e2017-01-25 00:46:091// Copyright 2016 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 "media/remoting/renderer_controller.h"
6
Gyuyoung Kim62a5de42018-01-10 09:48:427#include <memory>
8
miu9f7788e2017-01-25 00:46:099#include "base/callback.h"
Alexander Timin4f9c35c2018-11-01 20:15:2010#include "base/message_loop/message_loop.h"
miu9f7788e2017-01-25 00:46:0911#include "base/run_loop.h"
Xiangjun Zhang8f6cf3b2017-08-02 07:12:4212#include "base/test/simple_test_tick_clock.h"
Anton Vayvod9ef77302017-08-08 20:54:0213#include "build/build_config.h"
miu9f7788e2017-01-25 00:46:0914#include "media/base/audio_decoder_config.h"
15#include "media/base/cdm_config.h"
16#include "media/base/limits.h"
17#include "media/base/media_util.h"
18#include "media/base/test_helpers.h"
19#include "media/base/video_decoder_config.h"
20#include "media/remoting/fake_remoter.h"
miu9f7788e2017-01-25 00:46:0921#include "mojo/public/cpp/bindings/strong_binding.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace media {
25namespace remoting {
26
27namespace {
28
Xiangjun Zhang6dc11102017-07-24 23:49:1129PipelineMetadata DefaultMetadata(VideoCodec codec) {
miu9f7788e2017-01-25 00:46:0930 PipelineMetadata data;
31 data.has_audio = true;
32 data.has_video = true;
Xiangjun Zhang6dc11102017-07-24 23:49:1133 data.video_decoder_config = TestVideoConfig::Normal(codec);
34 data.audio_decoder_config = TestAudioConfig::Normal();
Xiangjun Zhang7fd5be0c2017-10-12 01:20:3035 data.natural_size = gfx::Size(1920, 1080);
miu9f7788e2017-01-25 00:46:0936 return data;
37}
38
Xiangjun Zhangba8724f482017-08-03 06:43:2539const std::string kDefaultReceiver = "TestingChromeCast";
40
Xiangjun Zhang6dc11102017-07-24 23:49:1141mojom::RemotingSinkMetadata GetDefaultSinkMetadata(bool enable) {
42 mojom::RemotingSinkMetadata metadata;
43 if (enable) {
44 metadata.features.push_back(mojom::RemotingSinkFeature::RENDERING);
45 metadata.features.push_back(mojom::RemotingSinkFeature::CONTENT_DECRYPTION);
46 } else {
47 metadata.features.clear();
48 }
49 metadata.video_capabilities.push_back(
50 mojom::RemotingSinkVideoCapability::CODEC_VP8);
51 metadata.audio_capabilities.push_back(
52 mojom::RemotingSinkAudioCapability::CODEC_BASELINE_SET);
Xiangjun Zhangba8724f482017-08-03 06:43:2553 metadata.friendly_name = kDefaultReceiver;
Xiangjun Zhang6dc11102017-07-24 23:49:1154 return metadata;
55}
56
Xiangjun Zhang8f6cf3b2017-08-02 07:12:4257constexpr base::TimeDelta kDelayedStartDuration =
58 base::TimeDelta::FromSeconds(5);
Xiangjun Zhang8f6cf3b2017-08-02 07:12:4259
miu9f7788e2017-01-25 00:46:0960} // namespace
61
xjz4e5d4bf32017-02-15 21:26:3562class RendererControllerTest : public ::testing::Test,
63 public MediaObserverClient {
miu9f7788e2017-01-25 00:46:0964 public:
Xiangjun Zhangacebf6502018-03-02 17:55:3265 RendererControllerTest()
66 : controller_(FakeRemoterFactory::CreateController(false)) {}
67
Chris Watkins2de69292017-12-01 03:08:0168 ~RendererControllerTest() override = default;
miu9f7788e2017-01-25 00:46:0969
70 void TearDown() final { RunUntilIdle(); }
71
72 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
73
xjz4e5d4bf32017-02-15 21:26:3574 // MediaObserverClient implementation.
Xiangjun Zhangba8724f482017-08-03 06:43:2575 void SwitchToRemoteRenderer(
76 const std::string& remote_device_friendly_name) override {
77 is_rendering_remotely_ = true;
78 disable_pipeline_suspend_ = true;
79 sink_name_ = remote_device_friendly_name;
80 }
81
Xiangjun Zhang5e20cba42018-01-10 19:54:5682 void SwitchToLocalRenderer(ReasonToSwitchToLocal reason) override {
Xiangjun Zhangba8724f482017-08-03 06:43:2583 is_rendering_remotely_ = false;
84 disable_pipeline_suspend_ = false;
85 sink_name_.clear();
xjz4e5d4bf32017-02-15 21:26:3586 }
87
88 void ActivateViewportIntersectionMonitoring(bool activate) override {
89 activate_viewport_intersection_monitoring_ = activate;
miu9f7788e2017-01-25 00:46:0990 }
91
Xiangjun Zhang4985fe22017-10-12 20:54:2292 double Duration() const override { return duration_in_sec_; }
93
Xiangjun Zhang7fd5be0c2017-10-12 01:20:3094 unsigned DecodedFrameCount() const override { return decoded_frames_; }
95
Anton Vayvod09fa66e2017-07-20 23:02:1296 void UpdateRemotePlaybackCompatibility(bool is_compatibe) override {}
97
miu9f7788e2017-01-25 00:46:0998 void CreateCdm(bool is_remoting) { is_remoting_cdm_ = is_remoting; }
99
Xiangjun Zhangc92ec9b2017-07-25 21:56:42100 void InitializeControllerAndBecomeDominant(
Xiangjun Zhang6dc11102017-07-24 23:49:11101 const PipelineMetadata& pipeline_metadata,
102 const mojom::RemotingSinkMetadata& sink_metadata) {
103 EXPECT_FALSE(is_rendering_remotely_);
Xiangjun Zhangba8724f482017-08-03 06:43:25104 EXPECT_TRUE(sink_name_.empty());
tzik2c963b872017-12-07 06:57:24105 controller_->clock_ = &clock_;
106 clock_.Advance(base::TimeDelta::FromSeconds(1));
Xiangjun Zhang6dc11102017-07-24 23:49:11107 controller_->SetClient(this);
108 RunUntilIdle();
109 EXPECT_FALSE(is_rendering_remotely_);
110 EXPECT_FALSE(activate_viewport_intersection_monitoring_);
111 EXPECT_FALSE(disable_pipeline_suspend_);
Xiangjun Zhangacebf6502018-03-02 17:55:32112 controller_->OnSinkAvailable(sink_metadata.Clone());
Xiangjun Zhang6dc11102017-07-24 23:49:11113 RunUntilIdle();
114 EXPECT_FALSE(is_rendering_remotely_);
115 EXPECT_FALSE(disable_pipeline_suspend_);
116 controller_->OnRemotePlaybackDisabled(false);
117 RunUntilIdle();
118 EXPECT_FALSE(is_rendering_remotely_);
119 EXPECT_FALSE(disable_pipeline_suspend_);
120 controller_->OnMetadataChanged(pipeline_metadata);
121 RunUntilIdle();
122 EXPECT_FALSE(is_rendering_remotely_);
123 EXPECT_FALSE(disable_pipeline_suspend_);
Xiangjun Zhangc92ec9b2017-07-25 21:56:42124 controller_->OnBecameDominantVisibleContent(true);
Xiangjun Zhang6dc11102017-07-24 23:49:11125 RunUntilIdle();
126 EXPECT_FALSE(is_rendering_remotely_);
127 EXPECT_FALSE(disable_pipeline_suspend_);
128 controller_->OnPlaying();
129 RunUntilIdle();
130 }
131
Xiangjun Zhangba8724f482017-08-03 06:43:25132 bool IsInDelayedStart() const {
Xiangjun Zhangc92ec9b2017-07-25 21:56:42133 return controller_->delayed_start_stability_timer_.IsRunning();
134 }
135
Xiangjun Zhang2cacf422017-11-29 02:22:50136 void DelayedStartEnds(double frame_rate = 30) {
Xiangjun Zhangc92ec9b2017-07-25 21:56:42137 EXPECT_TRUE(IsInDelayedStart());
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30138 decoded_frames_ = frame_rate * kDelayedStartDuration.InSeconds();
tzik2c963b872017-12-07 06:57:24139 clock_.Advance(kDelayedStartDuration);
Xiangjun Zhang8f6cf3b2017-08-02 07:12:42140 RunUntilIdle();
tzikf550a612018-07-12 02:25:34141 controller_->delayed_start_stability_timer_.FireNow();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42142 }
143
Xiangjun Zhangba8724f482017-08-03 06:43:25144 void ExpectInDelayedStart() const {
145 EXPECT_FALSE(is_rendering_remotely_);
146 EXPECT_FALSE(disable_pipeline_suspend_);
147 EXPECT_TRUE(sink_name_.empty());
148 EXPECT_TRUE(IsInDelayedStart());
149 EXPECT_TRUE(activate_viewport_intersection_monitoring_);
150 }
151
152 void ExpectInRemoting() const {
153 EXPECT_TRUE(is_rendering_remotely_);
154 EXPECT_TRUE(disable_pipeline_suspend_);
155 EXPECT_EQ(kDefaultReceiver, sink_name_);
156 EXPECT_FALSE(IsInDelayedStart());
157 EXPECT_TRUE(activate_viewport_intersection_monitoring_);
158 }
159
160 void ExpectInLocalRendering() const {
161 EXPECT_FALSE(is_rendering_remotely_);
162 EXPECT_FALSE(disable_pipeline_suspend_);
163 EXPECT_TRUE(sink_name_.empty());
164 EXPECT_FALSE(IsInDelayedStart());
165 }
166
miu9f7788e2017-01-25 00:46:09167 base::MessageLoop message_loop_;
168
169 protected:
miu9f7788e2017-01-25 00:46:09170 bool is_rendering_remotely_ = false;
171 bool is_remoting_cdm_ = false;
xjz4e5d4bf32017-02-15 21:26:35172 bool activate_viewport_intersection_monitoring_ = false;
173 bool disable_pipeline_suspend_ = false;
Xiangjun Zhang8f6cf3b2017-08-02 07:12:42174 size_t decoded_bytes_ = 0;
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30175 unsigned decoded_frames_ = 0;
tzik2c963b872017-12-07 06:57:24176 base::SimpleTestTickClock clock_;
Xiangjun Zhangba8724f482017-08-03 06:43:25177 std::string sink_name_;
178 std::unique_ptr<RendererController> controller_;
Xiangjun Zhang4985fe22017-10-12 20:54:22179 double duration_in_sec_ = 120; // 2m duration.
miu9f7788e2017-01-25 00:46:09180
181 private:
182 DISALLOW_COPY_AND_ASSIGN(RendererControllerTest);
183};
184
Xiangjun Zhangc92ec9b2017-07-25 21:56:42185TEST_F(RendererControllerTest, ToggleRendererOnDominantChange) {
Xiangjun Zhangacebf6502018-03-02 17:55:32186 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
Xiangjun Zhangc92ec9b2017-07-25 21:56:42187 GetDefaultSinkMetadata(true));
Xiangjun Zhang2cacf422017-11-29 02:22:50188 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42189 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25190 ExpectInRemoting(); // All requirements now satisfied.
miu9f7788e2017-01-25 00:46:09191
192 // Leaving fullscreen should shut down remoting.
Xiangjun Zhangc92ec9b2017-07-25 21:56:42193 controller_->OnBecameDominantVisibleContent(false);
miu9f7788e2017-01-25 00:46:09194 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25195 ExpectInLocalRendering();
miu9f7788e2017-01-25 00:46:09196}
197
miu9f7788e2017-01-25 00:46:09198TEST_F(RendererControllerTest, ToggleRendererOnDisableChange) {
199 EXPECT_FALSE(is_rendering_remotely_);
Xiangjun Zhangacebf6502018-03-02 17:55:32200 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
Xiangjun Zhangc92ec9b2017-07-25 21:56:42201 GetDefaultSinkMetadata(true));
Xiangjun Zhangba8724f482017-08-03 06:43:25202 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50203 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42204 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25205 ExpectInRemoting(); // All requirements now satisfied.
miu9f7788e2017-01-25 00:46:09206
207 // If the page disables remote playback (e.g., by setting the
208 // disableRemotePlayback attribute), this should shut down remoting.
209 controller_->OnRemotePlaybackDisabled(true);
210 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25211 ExpectInLocalRendering();
miu9f7788e2017-01-25 00:46:09212}
213
Xiangjun Zhang4985fe22017-10-12 20:54:22214TEST_F(RendererControllerTest, NotStartForShortContent) {
Xiangjun Zhang4985fe22017-10-12 20:54:22215 duration_in_sec_ = 30;
Xiangjun Zhangacebf6502018-03-02 17:55:32216 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
Xiangjun Zhang4985fe22017-10-12 20:54:22217 GetDefaultSinkMetadata(true));
218 ExpectInLocalRendering();
219}
220
Xiangjun Zhangacebf6502018-03-02 17:55:32221TEST_F(RendererControllerTest, ToggleRendererOnSinkCapabilities) {
222 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
223 GetDefaultSinkMetadata(false));
224 // An available sink that does not support remote rendering should not cause
225 // the controller to toggle remote rendering on.
226 ExpectInLocalRendering();
227 controller_->OnSinkGone(); // Bye-bye useless sink!
228 RunUntilIdle();
229 ExpectInLocalRendering();
230 // A sink that *does* support remote rendering *does* cause the controller to
231 // toggle remote rendering on.
232 controller_->OnSinkAvailable(GetDefaultSinkMetadata(true).Clone());
233 RunUntilIdle();
234 EXPECT_TRUE(activate_viewport_intersection_monitoring_);
235 EXPECT_FALSE(is_rendering_remotely_);
236 controller_->OnBecameDominantVisibleContent(true);
237 RunUntilIdle();
238 ExpectInDelayedStart();
239 DelayedStartEnds();
240 RunUntilIdle();
241 ExpectInRemoting(); // All requirements now satisfied.
242}
243
Xiangjun Zhang6dc11102017-07-24 23:49:11244TEST_F(RendererControllerTest, WithVP9VideoCodec) {
Xiangjun Zhangacebf6502018-03-02 17:55:32245 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP9),
Xiangjun Zhangc92ec9b2017-07-25 21:56:42246 GetDefaultSinkMetadata(true));
Xiangjun Zhang6dc11102017-07-24 23:49:11247 // An available sink that does not support VP9 video codec should not cause
248 // the controller to toggle remote rendering on.
Xiangjun Zhangba8724f482017-08-03 06:43:25249 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11250
Xiangjun Zhangacebf6502018-03-02 17:55:32251 controller_->OnSinkGone(); // Bye-bye useless sink!
Xiangjun Zhang6dc11102017-07-24 23:49:11252 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
253 sink_metadata.video_capabilities.push_back(
254 mojom::RemotingSinkVideoCapability::CODEC_VP9);
255 // A sink that *does* support VP9 video codec *does* cause the controller to
256 // toggle remote rendering on.
Xiangjun Zhangacebf6502018-03-02 17:55:32257 controller_->OnSinkAvailable(sink_metadata.Clone());
Xiangjun Zhang6dc11102017-07-24 23:49:11258 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25259 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50260 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42261 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25262 ExpectInRemoting(); // All requirements now satisfied.
Xiangjun Zhang6dc11102017-07-24 23:49:11263}
264
265TEST_F(RendererControllerTest, WithHEVCVideoCodec) {
Xiangjun Zhangacebf6502018-03-02 17:55:32266 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecHEVC),
Xiangjun Zhangc92ec9b2017-07-25 21:56:42267 GetDefaultSinkMetadata(true));
Xiangjun Zhang6dc11102017-07-24 23:49:11268 // An available sink that does not support HEVC video codec should not cause
269 // the controller to toggle remote rendering on.
Xiangjun Zhangba8724f482017-08-03 06:43:25270 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11271
Xiangjun Zhangacebf6502018-03-02 17:55:32272 controller_->OnSinkGone(); // Bye-bye useless sink!
miu9f7788e2017-01-25 00:46:09273 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25274 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11275 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
276 sink_metadata.video_capabilities.push_back(
277 mojom::RemotingSinkVideoCapability::CODEC_HEVC);
278 // A sink that *does* support HEVC video codec *does* cause the controller to
279 // toggle remote rendering on.
Xiangjun Zhangacebf6502018-03-02 17:55:32280 controller_->OnSinkAvailable(sink_metadata.Clone());
Xiangjun Zhang6dc11102017-07-24 23:49:11281 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25282 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50283 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42284 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25285 ExpectInRemoting(); // All requirements now satisfied.
Xiangjun Zhang6dc11102017-07-24 23:49:11286}
287
288TEST_F(RendererControllerTest, WithAACAudioCodec) {
Xiangjun Zhang6dc11102017-07-24 23:49:11289 const AudioDecoderConfig audio_config = AudioDecoderConfig(
290 AudioCodec::kCodecAAC, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO,
291 44100, EmptyExtraData(), Unencrypted());
292 PipelineMetadata pipeline_metadata = DefaultMetadata(VideoCodec::kCodecVP8);
293 pipeline_metadata.audio_decoder_config = audio_config;
Xiangjun Zhangacebf6502018-03-02 17:55:32294 InitializeControllerAndBecomeDominant(pipeline_metadata,
Xiangjun Zhangc92ec9b2017-07-25 21:56:42295 GetDefaultSinkMetadata(true));
Xiangjun Zhang6dc11102017-07-24 23:49:11296 // An available sink that does not support AAC audio codec should not cause
297 // the controller to toggle remote rendering on.
Xiangjun Zhangba8724f482017-08-03 06:43:25298 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11299
Xiangjun Zhangacebf6502018-03-02 17:55:32300 controller_->OnSinkGone(); // Bye-bye useless sink!
miu9f7788e2017-01-25 00:46:09301 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25302 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11303 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
304 sink_metadata.audio_capabilities.push_back(
305 mojom::RemotingSinkAudioCapability::CODEC_AAC);
306 // A sink that *does* support AAC audio codec *does* cause the controller to
307 // toggle remote rendering on.
Xiangjun Zhangacebf6502018-03-02 17:55:32308 controller_->OnSinkAvailable(sink_metadata.Clone());
miu9f7788e2017-01-25 00:46:09309 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25310 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50311 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42312 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25313 ExpectInRemoting(); // All requirements now satisfied.
Xiangjun Zhang6dc11102017-07-24 23:49:11314}
315
316TEST_F(RendererControllerTest, WithOpusAudioCodec) {
Xiangjun Zhang6dc11102017-07-24 23:49:11317 const AudioDecoderConfig audio_config = AudioDecoderConfig(
318 AudioCodec::kCodecOpus, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO,
319 44100, EmptyExtraData(), Unencrypted());
320 PipelineMetadata pipeline_metadata = DefaultMetadata(VideoCodec::kCodecVP8);
321 pipeline_metadata.audio_decoder_config = audio_config;
Xiangjun Zhangacebf6502018-03-02 17:55:32322 InitializeControllerAndBecomeDominant(pipeline_metadata,
Xiangjun Zhangc92ec9b2017-07-25 21:56:42323 GetDefaultSinkMetadata(true));
Xiangjun Zhang6dc11102017-07-24 23:49:11324 // An available sink that does not support Opus audio codec should not cause
325 // the controller to toggle remote rendering on.
Xiangjun Zhangba8724f482017-08-03 06:43:25326 ExpectInLocalRendering();
Xiangjun Zhang6dc11102017-07-24 23:49:11327
Xiangjun Zhangacebf6502018-03-02 17:55:32328 controller_->OnSinkGone(); // Bye-bye useless sink!
Xiangjun Zhang6dc11102017-07-24 23:49:11329 RunUntilIdle();
Xiangjun Zhang6dc11102017-07-24 23:49:11330 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
331 sink_metadata.audio_capabilities.push_back(
332 mojom::RemotingSinkAudioCapability::CODEC_OPUS);
333 // A sink that *does* support Opus audio codec *does* cause the controller to
334 // toggle remote rendering on.
Xiangjun Zhangacebf6502018-03-02 17:55:32335 controller_->OnSinkAvailable(sink_metadata.Clone());
Xiangjun Zhang6dc11102017-07-24 23:49:11336 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25337 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50338 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42339 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25340 ExpectInRemoting(); // All requirements now satisfied.
Xiangjun Zhang6dc11102017-07-24 23:49:11341}
342
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30343TEST_F(RendererControllerTest, StartFailedWithHighFrameRate) {
Xiangjun Zhangacebf6502018-03-02 17:55:32344 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30345 GetDefaultSinkMetadata(true));
346 RunUntilIdle();
347 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50348 DelayedStartEnds(60);
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30349 RunUntilIdle();
350 ExpectInLocalRendering();
351}
352
353TEST_F(RendererControllerTest, StartSuccessWithHighFrameRate) {
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30354 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
355 sink_metadata.video_capabilities.push_back(
356 mojom::RemotingSinkVideoCapability::SUPPORT_4K);
Xiangjun Zhangacebf6502018-03-02 17:55:32357 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
358 sink_metadata);
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30359 RunUntilIdle();
360 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50361 DelayedStartEnds(60);
Xiangjun Zhang7fd5be0c2017-10-12 01:20:30362 RunUntilIdle();
363 ExpectInRemoting();
364}
365
Xiangjun Zhang4e722f42017-11-29 20:39:03366TEST_F(RendererControllerTest, PacingTooSlowly) {
Xiangjun Zhang4e722f42017-11-29 20:39:03367 mojom::RemotingSinkMetadata sink_metadata = GetDefaultSinkMetadata(true);
Xiangjun Zhangacebf6502018-03-02 17:55:32368 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
369 sink_metadata);
Xiangjun Zhang4e722f42017-11-29 20:39:03370 RunUntilIdle();
371 ExpectInDelayedStart();
372 DelayedStartEnds(false);
373 RunUntilIdle();
374 ExpectInRemoting(); // All requirements now satisfied.
375 controller_->OnRendererFatalError(StopTrigger::PACING_TOO_SLOWLY);
376 RunUntilIdle();
377 ExpectInLocalRendering();
Xiangjun Zhangacebf6502018-03-02 17:55:32378 controller_->OnSinkAvailable(sink_metadata.Clone());
Xiangjun Zhang4e722f42017-11-29 20:39:03379 RunUntilIdle();
380 controller_->OnBecameDominantVisibleContent(false);
381 RunUntilIdle();
382 ExpectInLocalRendering();
383 controller_->OnBecameDominantVisibleContent(true);
384 RunUntilIdle();
385 ExpectInDelayedStart(); // Try start remoting again.
386}
387
Xiangjun Zhang6dc11102017-07-24 23:49:11388TEST_F(RendererControllerTest, StartFailed) {
Xiangjun Zhangacebf6502018-03-02 17:55:32389 controller_ = FakeRemoterFactory::CreateController(true);
390 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
Xiangjun Zhangc92ec9b2017-07-25 21:56:42391 GetDefaultSinkMetadata(true));
392 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25393 ExpectInDelayedStart();
Xiangjun Zhang2cacf422017-11-29 02:22:50394 DelayedStartEnds();
Xiangjun Zhangc92ec9b2017-07-25 21:56:42395 RunUntilIdle();
Xiangjun Zhangba8724f482017-08-03 06:43:25396 ExpectInLocalRendering();
miu9f7788e2017-01-25 00:46:09397}
398
Dale Curtisc96a3542018-12-17 22:15:23399TEST_F(RendererControllerTest, SetClientNullptr) {
400 controller_ = FakeRemoterFactory::CreateController(true);
401 InitializeControllerAndBecomeDominant(DefaultMetadata(VideoCodec::kCodecVP8),
402 GetDefaultSinkMetadata(true));
403 RunUntilIdle();
404 controller_->SetClient(nullptr);
405 RunUntilIdle();
406 ExpectInLocalRendering();
407}
408
miu9f7788e2017-01-25 00:46:09409} // namespace remoting
410} // namespace media