Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / media / remoting / receiver_controller.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_controller.h"
6
7 #include "base/no_destructor.h"
8 #include "base/task/single_thread_task_runner.h"
9
10 namespace media {
11 namespace remoting {
12
13 // static
14 ReceiverController* ReceiverController::GetInstance() {
15   static base::NoDestructor<ReceiverController> controller;
16   return controller.get();
17 }
18
19 ReceiverController::ReceiverController()
20     : rpc_messenger_([this](std::vector<uint8_t> message) {
21         OnSendRpc(std::move(message));
22       }),
23       main_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {}
24
25 ReceiverController::~ReceiverController() = default;
26
27 void ReceiverController::Initialize(
28     mojo::PendingRemote<mojom::Remotee> remotee) {
29   DCHECK(main_task_runner_->BelongsToCurrentThread());
30   DCHECK(!media_remotee_.is_bound());
31   media_remotee_.Bind(std::move(remotee));
32
33   // Calling NotifyRemotingSinkReady() to notify the host that RemotingSink is
34   // ready.
35   media_remotee_->OnRemotingSinkReady(receiver_.BindNewPipeAndPassRemote());
36 }
37
38 void ReceiverController::OnRendererFlush(uint32_t audio_count,
39                                          uint32_t video_count) {
40   if (!main_task_runner_->BelongsToCurrentThread()) {
41     // |this| is a singleton per process, it would be safe to use
42     // base::Unretained() here.
43     main_task_runner_->PostTask(
44         FROM_HERE,
45         base::BindOnce(&ReceiverController::OnRendererFlush,
46                        base::Unretained(this), audio_count, video_count));
47     return;
48   }
49
50   if (media_remotee_.is_bound())
51     media_remotee_->OnFlushUntil(audio_count, video_count);
52 }
53
54 void ReceiverController::OnVideoNaturalSizeChange(const gfx::Size& size) {
55   if (!main_task_runner_->BelongsToCurrentThread()) {
56     // |this| is a singleton per process, it would be safe to use
57     // base::Unretained() here.
58     main_task_runner_->PostTask(
59         FROM_HERE, base::BindOnce(&ReceiverController::OnVideoNaturalSizeChange,
60                                   base::Unretained(this), size));
61     return;
62   }
63
64   if (media_remotee_.is_bound())
65     media_remotee_->OnVideoNaturalSizeChange(size);
66 }
67
68 void ReceiverController::StartDataStreams(
69     mojo::PendingRemote<::media::mojom::RemotingDataStreamReceiver>
70         audio_stream,
71     mojo::PendingRemote<::media::mojom::RemotingDataStreamReceiver>
72         video_stream) {
73   if (!main_task_runner_->BelongsToCurrentThread()) {
74     // |this| is a singleton per process, it would be safe to use
75     // base::Unretained() here.
76     main_task_runner_->PostTask(
77         FROM_HERE,
78         base::BindOnce(&ReceiverController::StartDataStreams,
79                        base::Unretained(this), std::move(audio_stream),
80                        std::move(video_stream)));
81     return;
82   }
83   if (media_remotee_.is_bound()) {
84     media_remotee_->StartDataStreams(std::move(audio_stream),
85                                      std::move(video_stream));
86   }
87 }
88
89 void ReceiverController::OnMessageFromSource(
90     const std::vector<uint8_t>& message) {
91   DCHECK(main_task_runner_->BelongsToCurrentThread());
92   auto rpc_message = std::make_unique<openscreen::cast::RpcMessage>(
93       openscreen::cast::RpcMessage());
94   if (!rpc_message->ParseFromArray(message.data(), message.size()))
95     return;
96
97   rpc_messenger_.ProcessMessageFromRemote(std::move(rpc_message));
98 }
99
100 void ReceiverController::OnSendRpc(std::vector<uint8_t> message) {
101   if (!main_task_runner_->BelongsToCurrentThread()) {
102     // |this| is a singleton per process, it would be safe to use
103     // base::Unretained() here.
104     main_task_runner_->PostTask(
105         FROM_HERE, base::BindOnce(&ReceiverController::OnSendRpc,
106                                   base::Unretained(this), std::move(message)));
107     return;
108   }
109
110   DCHECK(media_remotee_.is_bound());
111   if (media_remotee_.is_bound())
112     media_remotee_->SendMessageToSource(message);
113 }
114
115 }  // namespace remoting
116 }  // namespace media