Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / media / remoting / receiver_unittest.cc
1 // Copyright 2020 The Chromium Authors
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/receiver.h"
6
7 #include <utility>
8
9 #include "base/check.h"
10 #include "base/memory/raw_ptr.h"
11 #include "base/task/single_thread_task_runner.h"
12 #include "base/test/gmock_callback_support.h"
13 #include "base/test/task_environment.h"
14 #include "media/base/audio_decoder_config.h"
15 #include "media/base/media_util.h"
16 #include "media/base/mock_filters.h"
17 #include "media/base/renderer.h"
18 #include "media/base/test_helpers.h"
19 #include "media/base/video_decoder_config.h"
20 #include "media/cast/openscreen/remoting_proto_enum_utils.h"
21 #include "media/cast/openscreen/remoting_proto_utils.h"
22 #include "media/remoting/mock_receiver_controller.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/abseil-cpp/absl/types/optional.h"
26
27 using base::test::RunOnceCallback;
28 using openscreen::cast::RpcMessenger;
29 using testing::_;
30 using testing::AtLeast;
31 using testing::NiceMock;
32 using testing::StrictMock;
33
34 namespace media {
35 namespace remoting {
36
37 class MockSender {
38  public:
39   MockSender(RpcMessenger* rpc_messenger, int remote_handle)
40       : rpc_messenger_(rpc_messenger),
41         rpc_handle_(rpc_messenger->GetUniqueHandle()),
42         remote_handle_(remote_handle) {
43     rpc_messenger_->RegisterMessageReceiverCallback(
44         rpc_handle_, [this](std::unique_ptr<openscreen::cast::RpcMessage> rpc) {
45           this->OnReceivedRpc(std::move(rpc));
46         });
47   }
48
49   MOCK_METHOD(void, AcquireRendererDone, ());
50   MOCK_METHOD(void, InitializeCallback, (bool));
51   MOCK_METHOD(void, FlushUntilCallback, ());
52   MOCK_METHOD(void, OnTimeUpdate, (int64_t, int64_t));
53   MOCK_METHOD(void, OnBufferingStateChange, (BufferingState));
54   MOCK_METHOD(void, OnEnded, ());
55   MOCK_METHOD(void, OnFatalError, ());
56   MOCK_METHOD(void, OnAudioConfigChange, (AudioDecoderConfig));
57   MOCK_METHOD(void, OnVideoConfigChange, (VideoDecoderConfig));
58   MOCK_METHOD(void, OnVideoNaturalSizeChange, (gfx::Size));
59   MOCK_METHOD(void, OnVideoOpacityChange, (bool));
60   MOCK_METHOD(void, OnStatisticsUpdate, (PipelineStatistics));
61   MOCK_METHOD(void, OnWaiting, ());
62
63   void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message) {
64     DCHECK(message);
65     switch (message->proc()) {
66       case openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER_DONE:
67         AcquireRendererDone();
68         break;
69       case openscreen::cast::RpcMessage::RPC_R_INITIALIZE_CALLBACK:
70         InitializeCallback(message->boolean_value());
71         break;
72       case openscreen::cast::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK:
73         FlushUntilCallback();
74         break;
75       case openscreen::cast::RpcMessage::RPC_RC_ONTIMEUPDATE: {
76         DCHECK(message->has_rendererclient_ontimeupdate_rpc());
77         const int64_t time_usec =
78             message->rendererclient_ontimeupdate_rpc().time_usec();
79         const int64_t max_time_usec =
80             message->rendererclient_ontimeupdate_rpc().max_time_usec();
81         OnTimeUpdate(time_usec, max_time_usec);
82         break;
83       }
84       case openscreen::cast::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE: {
85         absl::optional<BufferingState> state =
86             media::cast::ToMediaBufferingState(
87                 message->rendererclient_onbufferingstatechange_rpc().state());
88         if (state.has_value())
89           OnBufferingStateChange(state.value());
90         break;
91       }
92       case openscreen::cast::RpcMessage::RPC_RC_ONENDED:
93         OnEnded();
94         break;
95       case openscreen::cast::RpcMessage::RPC_RC_ONERROR:
96         OnFatalError();
97         break;
98       case openscreen::cast::RpcMessage::RPC_RC_ONAUDIOCONFIGCHANGE: {
99         DCHECK(message->has_rendererclient_onaudioconfigchange_rpc());
100         const auto* audio_config_message =
101             message->mutable_rendererclient_onaudioconfigchange_rpc();
102         const openscreen::cast::AudioDecoderConfig pb_audio_config =
103             audio_config_message->audio_decoder_config();
104         AudioDecoderConfig out_audio_config;
105         media::cast::ConvertProtoToAudioDecoderConfig(pb_audio_config,
106                                                       &out_audio_config);
107         DCHECK(out_audio_config.IsValidConfig());
108         OnAudioConfigChange(out_audio_config);
109         break;
110       }
111       case openscreen::cast::RpcMessage::RPC_RC_ONVIDEOCONFIGCHANGE: {
112         DCHECK(message->has_rendererclient_onvideoconfigchange_rpc());
113         const auto* video_config_message =
114             message->mutable_rendererclient_onvideoconfigchange_rpc();
115         const openscreen::cast::VideoDecoderConfig pb_video_config =
116             video_config_message->video_decoder_config();
117         VideoDecoderConfig out_video_config;
118         media::cast::ConvertProtoToVideoDecoderConfig(pb_video_config,
119                                                       &out_video_config);
120         DCHECK(out_video_config.IsValidConfig());
121
122         OnVideoConfigChange(out_video_config);
123         break;
124       }
125       case openscreen::cast::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE: {
126         DCHECK(message->has_rendererclient_onvideonatualsizechange_rpc());
127
128         gfx::Size size(
129             message->rendererclient_onvideonatualsizechange_rpc().width(),
130             message->rendererclient_onvideonatualsizechange_rpc().height());
131         OnVideoNaturalSizeChange(size);
132         break;
133       }
134       case openscreen::cast::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE:
135         OnVideoOpacityChange(message->boolean_value());
136         break;
137       case openscreen::cast::RpcMessage::RPC_RC_ONSTATISTICSUPDATE: {
138         DCHECK(message->has_rendererclient_onstatisticsupdate_rpc());
139         auto rpc_message = message->rendererclient_onstatisticsupdate_rpc();
140         PipelineStatistics statistics;
141         statistics.audio_bytes_decoded = rpc_message.audio_bytes_decoded();
142         statistics.video_bytes_decoded = rpc_message.video_bytes_decoded();
143         statistics.video_frames_decoded = rpc_message.video_frames_decoded();
144         statistics.video_frames_dropped = rpc_message.video_frames_dropped();
145         statistics.audio_memory_usage = rpc_message.audio_memory_usage();
146         statistics.video_memory_usage = rpc_message.video_memory_usage();
147         OnStatisticsUpdate(statistics);
148         break;
149       }
150
151       default:
152         VLOG(1) << "Unknown RPC: " << message->proc();
153     }
154   }
155
156   void SendRpcAcquireRenderer() {
157     openscreen::cast::RpcMessage rpc;
158     rpc.set_handle(RpcMessenger::kAcquireRendererHandle);
159     rpc.set_proc(openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER);
160     rpc.set_integer_value(rpc_handle_);
161     rpc_messenger_->SendMessageToRemote(rpc);
162   }
163
164   void SendRpcInitialize() {
165     openscreen::cast::RpcMessage rpc;
166     rpc.set_handle(remote_handle_);
167     rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_INITIALIZE);
168     rpc_messenger_->SendMessageToRemote(rpc);
169   }
170
171   void SendRpcSetPlaybackRate(double playback_rate) {
172     openscreen::cast::RpcMessage rpc;
173     rpc.set_handle(remote_handle_);
174     rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_SETPLAYBACKRATE);
175     rpc.set_double_value(playback_rate);
176     rpc_messenger_->SendMessageToRemote(rpc);
177   }
178
179   void SendRpcFlushUntil(uint32_t audio_count, uint32_t video_count) {
180     openscreen::cast::RpcMessage rpc;
181     rpc.set_handle(remote_handle_);
182     rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_FLUSHUNTIL);
183     openscreen::cast::RendererFlushUntil* message =
184         rpc.mutable_renderer_flushuntil_rpc();
185     message->set_audio_count(audio_count);
186     message->set_video_count(video_count);
187     message->set_callback_handle(rpc_handle_);
188     rpc_messenger_->SendMessageToRemote(rpc);
189   }
190
191   void SendRpcStartPlayingFrom(base::TimeDelta time) {
192     openscreen::cast::RpcMessage rpc;
193     rpc.set_handle(remote_handle_);
194     rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_STARTPLAYINGFROM);
195     rpc.set_integer64_value(time.InMicroseconds());
196     rpc_messenger_->SendMessageToRemote(rpc);
197   }
198
199   void SendRpcSetVolume(float volume) {
200     openscreen::cast::RpcMessage rpc;
201     rpc.set_handle(remote_handle_);
202     rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_SETVOLUME);
203     rpc.set_double_value(volume);
204     rpc_messenger_->SendMessageToRemote(rpc);
205   }
206
207  private:
208   const raw_ptr<RpcMessenger> rpc_messenger_;
209   const int rpc_handle_;
210   const int remote_handle_;
211 };
212
213 class ReceiverTest : public ::testing::Test {
214  public:
215   ReceiverTest() = default;
216
217   void SetUp() override {
218     mock_controller_ = MockReceiverController::GetInstance();
219     mock_controller_->Initialize(
220         mock_controller_->mock_remotee()->BindNewPipeAndPassRemote());
221     mock_remotee_ = mock_controller_->mock_remotee();
222
223     rpc_messenger_ = mock_controller_->rpc_messenger();
224     receiver_renderer_handle_ = rpc_messenger_->GetUniqueHandle();
225
226     mock_sender_ = std::make_unique<StrictMock<MockSender>>(
227         rpc_messenger_, receiver_renderer_handle_);
228
229     rpc_messenger_->RegisterMessageReceiverCallback(
230         RpcMessenger::kAcquireRendererHandle,
231         [ptr = weak_factory_.GetWeakPtr()](
232             std::unique_ptr<openscreen::cast::RpcMessage> message) {
233           if (ptr) {
234             ptr->OnReceivedRpc(std::move(message));
235           }
236         });
237   }
238
239   void TearDown() override {
240     rpc_messenger_->UnregisterMessageReceiverCallback(
241         RpcMessenger::kAcquireRendererHandle);
242   }
243
244   void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message) {
245     DCHECK(message);
246     EXPECT_EQ(message->proc(),
247               openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER);
248     OnAcquireRenderer(std::move(message));
249   }
250
251   void OnAcquireRenderer(
252       std::unique_ptr<openscreen::cast::RpcMessage> message) {
253     DCHECK(message->has_integer_value());
254     DCHECK(message->integer_value() != RpcMessenger::kInvalidHandle);
255
256     if (sender_renderer_handle_ == RpcMessenger::kInvalidHandle) {
257       sender_renderer_handle_ = message->integer_value();
258       SetRemoteHandle();
259     }
260   }
261
262   void OnAcquireRendererDone(int receiver_renderer_handle) {
263     DVLOG(3) << __func__
264              << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle="
265              << sender_renderer_handle_
266              << " rpc_handle=" << receiver_renderer_handle;
267     openscreen::cast::RpcMessage rpc;
268     rpc.set_handle(sender_renderer_handle_);
269     rpc.set_proc(openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER_DONE);
270     rpc.set_integer_value(receiver_renderer_handle);
271     rpc_messenger_->SendMessageToRemote(rpc);
272   }
273
274   void CreateReceiver() {
275     auto renderer = std::make_unique<NiceMock<MockRenderer>>();
276     mock_renderer_ = renderer.get();
277     receiver_ = std::make_unique<Receiver>(
278         receiver_renderer_handle_, sender_renderer_handle_, mock_controller_,
279         base::SingleThreadTaskRunner::GetCurrentDefault(), std::move(renderer),
280         base::BindOnce(&ReceiverTest::OnAcquireRendererDone,
281                        weak_factory_.GetWeakPtr()));
282   }
283
284   void SetRemoteHandle() {
285     if (!receiver_)
286       return;
287     receiver_->SetRemoteHandle(sender_renderer_handle_);
288   }
289
290   void InitializeReceiver() {
291     receiver_->Initialize(&mock_media_resource_, nullptr,
292                           base::BindOnce(&ReceiverTest::OnRendererInitialized,
293                                          weak_factory_.GetWeakPtr()));
294   }
295
296   MOCK_METHOD(void, OnRendererInitialized, (PipelineStatus));
297
298   base::test::TaskEnvironment task_environment_;
299
300   int sender_renderer_handle_ = RpcMessenger::kInvalidHandle;
301   int receiver_renderer_handle_ = RpcMessenger::kInvalidHandle;
302
303   MockMediaResource mock_media_resource_;
304   std::unique_ptr<MockSender> mock_sender_;
305   raw_ptr<RpcMessenger> rpc_messenger_ = nullptr;
306   raw_ptr<MockRemotee> mock_remotee_;
307   raw_ptr<MockReceiverController> mock_controller_ = nullptr;
308   std::unique_ptr<Receiver> receiver_;
309   raw_ptr<MockRenderer> mock_renderer_ = nullptr;
310
311   base::WeakPtrFactory<ReceiverTest> weak_factory_{this};
312 };
313
314 TEST_F(ReceiverTest, AcquireRendererBeforeCreateReceiver) {
315   mock_sender_->SendRpcAcquireRenderer();
316   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
317   CreateReceiver();
318   task_environment_.RunUntilIdle();
319 }
320
321 TEST_F(ReceiverTest, AcquireRendererAfterCreateReceiver) {
322   CreateReceiver();
323   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
324   mock_sender_->SendRpcAcquireRenderer();
325   task_environment_.RunUntilIdle();
326 }
327
328 // |Receiver::Initialize| will be called by the local pipeline, and the
329 // |Receiver::RpcInitialize| will be called once it received the
330 // RPC_R_INITIALIZE messages, so these two initialization functions are possible
331 // to be called in difference orders.
332 //
333 // Call |Receiver::Initialize| first, then send RPC_R_INITIALIZE.
334 TEST_F(ReceiverTest, InitializeBeforeRpcInitialize) {
335   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
336   mock_sender_->SendRpcAcquireRenderer();
337   CreateReceiver();
338
339   EXPECT_CALL(*mock_renderer_,
340               OnInitialize(&mock_media_resource_, receiver_.get(), _))
341       .WillOnce(RunOnceCallback<2>(PIPELINE_OK));
342   EXPECT_CALL(*this, OnRendererInitialized(HasStatusCode(PIPELINE_OK)))
343       .Times(1);
344   EXPECT_CALL(*mock_sender_, InitializeCallback(true)).Times(1);
345
346   InitializeReceiver();
347   mock_sender_->SendRpcInitialize();
348   task_environment_.RunUntilIdle();
349 }
350
351 // Send RPC_R_INITIALIZE first, then call |Receiver::Initialize|.
352 TEST_F(ReceiverTest, InitializeAfterRpcInitialize) {
353   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
354   mock_sender_->SendRpcAcquireRenderer();
355   CreateReceiver();
356
357   EXPECT_CALL(*mock_renderer_,
358               OnInitialize(&mock_media_resource_, receiver_.get(), _))
359       .WillOnce(RunOnceCallback<2>(PIPELINE_OK));
360   EXPECT_CALL(*this, OnRendererInitialized(HasStatusCode(PIPELINE_OK)))
361       .Times(1);
362   EXPECT_CALL(*mock_sender_, InitializeCallback(true)).Times(1);
363
364   mock_sender_->SendRpcInitialize();
365   InitializeReceiver();
366   task_environment_.RunUntilIdle();
367 }
368
369 TEST_F(ReceiverTest, RpcRendererMessages) {
370   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
371   mock_sender_->SendRpcAcquireRenderer();
372   CreateReceiver();
373   mock_sender_->SendRpcInitialize();
374   InitializeReceiver();
375   task_environment_.RunUntilIdle();
376
377   // SetVolume
378   const float volume = 0.5;
379   EXPECT_CALL(*mock_renderer_, SetVolume(volume)).Times(1);
380   mock_sender_->SendRpcSetVolume(volume);
381   task_environment_.RunUntilIdle();
382
383   EXPECT_CALL(*mock_sender_, OnTimeUpdate(_, _)).Times(AtLeast(1));
384
385   // SetPlaybackRate
386   const double playback_rate = 1.2;
387   EXPECT_CALL(*mock_renderer_, SetPlaybackRate(playback_rate)).Times(1);
388   mock_sender_->SendRpcSetPlaybackRate(playback_rate);
389   task_environment_.RunUntilIdle();
390
391   // Flush
392   const uint32_t flush_audio_count = 10;
393   const uint32_t flush_video_count = 20;
394   EXPECT_CALL(*mock_renderer_, OnFlush(_)).WillOnce(RunOnceCallback<0>());
395   EXPECT_CALL(*mock_sender_, FlushUntilCallback()).Times(1);
396   mock_sender_->SendRpcFlushUntil(flush_audio_count, flush_video_count);
397   task_environment_.RunUntilIdle();
398   EXPECT_EQ(flush_audio_count, mock_remotee_->flush_audio_count());
399   EXPECT_EQ(flush_video_count, mock_remotee_->flush_video_count());
400
401   // StartPlayingFrom
402   const base::TimeDelta time = base::Seconds(100);
403   EXPECT_CALL(*mock_renderer_, StartPlayingFrom(time)).Times(1);
404   mock_sender_->SendRpcStartPlayingFrom(time);
405   task_environment_.RunUntilIdle();
406 }
407
408 TEST_F(ReceiverTest, RendererClientInterface) {
409   EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
410   mock_sender_->SendRpcAcquireRenderer();
411   CreateReceiver();
412   mock_sender_->SendRpcInitialize();
413   InitializeReceiver();
414   task_environment_.RunUntilIdle();
415
416   // OnBufferingStateChange
417   EXPECT_CALL(*mock_sender_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
418       .Times(1);
419   receiver_->OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
420                                     BUFFERING_CHANGE_REASON_UNKNOWN);
421   task_environment_.RunUntilIdle();
422
423   // OnEnded
424   EXPECT_CALL(*mock_sender_, OnEnded()).Times(1);
425   receiver_->OnEnded();
426   task_environment_.RunUntilIdle();
427
428   // OnError
429   EXPECT_CALL(*mock_sender_, OnFatalError()).Times(1);
430   receiver_->OnError(AUDIO_RENDERER_ERROR);
431   task_environment_.RunUntilIdle();
432
433   // OnAudioConfigChange
434   const auto kNewAudioConfig = TestAudioConfig::Normal();
435   EXPECT_CALL(*mock_sender_,
436               OnAudioConfigChange(DecoderConfigEq(kNewAudioConfig)))
437       .Times(1);
438   receiver_->OnAudioConfigChange(kNewAudioConfig);
439   task_environment_.RunUntilIdle();
440
441   // OnVideoConfigChange
442   const auto kNewVideoConfig = TestVideoConfig::Normal();
443   EXPECT_CALL(*mock_sender_,
444               OnVideoConfigChange(DecoderConfigEq(kNewVideoConfig)))
445       .Times(1);
446   receiver_->OnVideoConfigChange(kNewVideoConfig);
447   task_environment_.RunUntilIdle();
448
449   // OnVideoNaturalSizeChange
450   const gfx::Size size(100, 200);
451   EXPECT_CALL(*mock_sender_, OnVideoNaturalSizeChange(size)).Times(1);
452   receiver_->OnVideoNaturalSizeChange(size);
453   task_environment_.RunUntilIdle();
454   EXPECT_EQ(size, mock_remotee_->changed_size());
455
456   // OnVideoOpacityChange
457   const bool opaque = true;
458   EXPECT_CALL(*mock_sender_, OnVideoOpacityChange(opaque)).Times(1);
459   receiver_->OnVideoOpacityChange(opaque);
460   task_environment_.RunUntilIdle();
461
462   // OnStatisticsUpdate
463   PipelineStatistics statistics;
464   statistics.audio_bytes_decoded = 100;
465   statistics.video_bytes_decoded = 200;
466   statistics.video_frames_decoded = 300;
467   statistics.video_frames_dropped = 400;
468   statistics.audio_memory_usage = 500;
469   statistics.video_memory_usage = 600;
470   EXPECT_CALL(*mock_sender_, OnStatisticsUpdate(statistics)).Times(1);
471   receiver_->OnStatisticsUpdate(statistics);
472   task_environment_.RunUntilIdle();
473 }
474
475 }  // namespace remoting
476 }  // namespace media