Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / media / remoting / remoting_renderer_factory.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/remoting_renderer_factory.h"
6
7 #include "base/task/bind_post_task.h"
8 #include "base/task/sequenced_task_runner.h"
9 #include "media/base/demuxer.h"
10 #include "media/cast/openscreen/remoting_message_factories.h"
11 #include "media/remoting/receiver.h"
12 #include "media/remoting/receiver_controller.h"
13 #include "media/remoting/stream_provider.h"
14
15 using openscreen::cast::RpcMessenger;
16
17 namespace media {
18 namespace remoting {
19
20 RemotingRendererFactory::RemotingRendererFactory(
21     mojo::PendingRemote<mojom::Remotee> remotee,
22     std::unique_ptr<RendererFactory> renderer_factory,
23     const scoped_refptr<base::SequencedTaskRunner>& media_task_runner)
24     : receiver_controller_(ReceiverController::GetInstance()),
25       rpc_messenger_(receiver_controller_->rpc_messenger()),
26       renderer_handle_(rpc_messenger_->GetUniqueHandle()),
27       waiting_for_remote_handle_receiver_(nullptr),
28       real_renderer_factory_(std::move(renderer_factory)),
29       media_task_runner_(media_task_runner) {
30   DVLOG(2) << __func__;
31   DCHECK(receiver_controller_);
32
33   // Register the callback to listen RPC_ACQUIRE_RENDERER message.
34   auto receive_callback = base::BindPostTask(
35       media_task_runner,
36       BindRepeating(&RemotingRendererFactory::OnAcquireRenderer,
37                     weak_factory_.GetWeakPtr()));
38   rpc_messenger_->RegisterMessageReceiverCallback(
39       RpcMessenger::kAcquireRendererHandle,
40       [cb = std::move(receive_callback)](
41           std::unique_ptr<openscreen::cast::RpcMessage> message) {
42         cb.Run(std::move(message));
43       });
44   receiver_controller_->Initialize(std::move(remotee));
45 }
46
47 RemotingRendererFactory::~RemotingRendererFactory() {
48   rpc_messenger_->UnregisterMessageReceiverCallback(
49       RpcMessenger::kAcquireRendererHandle);
50 }
51
52 std::unique_ptr<Renderer> RemotingRendererFactory::CreateRenderer(
53     const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
54     const scoped_refptr<base::TaskRunner>& worker_task_runner,
55     AudioRendererSink* audio_renderer_sink,
56     VideoRendererSink* video_renderer_sink,
57     RequestOverlayInfoCB request_overlay_info_cb,
58     const gfx::ColorSpace& target_color_space) {
59   DVLOG(2) << __func__;
60
61   auto receiver = std::make_unique<Receiver>(
62       renderer_handle_, remote_renderer_handle_, receiver_controller_,
63       media_task_runner,
64       real_renderer_factory_->CreateRenderer(
65           media_task_runner, worker_task_runner, audio_renderer_sink,
66           video_renderer_sink, request_overlay_info_cb, target_color_space),
67       base::BindOnce(&RemotingRendererFactory::OnAcquireRendererDone,
68                      base::Unretained(this)));
69
70   // If we haven't received a RPC_ACQUIRE_RENDERER yet, keep a reference to
71   // |receiver|, and set its remote handle when we get the call to
72   // OnAcquireRenderer().
73   if (remote_renderer_handle_ == RpcMessenger::kInvalidHandle)
74     waiting_for_remote_handle_receiver_ = receiver->GetWeakPtr();
75
76   return std::move(receiver);
77 }
78
79 void RemotingRendererFactory::OnReceivedRpc(
80     std::unique_ptr<openscreen::cast::RpcMessage> message) {
81   DCHECK(message);
82   if (message->proc() == openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER)
83     OnAcquireRenderer(std::move(message));
84   else
85     VLOG(1) << __func__ << ": Unknow RPC message. proc=" << message->proc();
86 }
87
88 void RemotingRendererFactory::OnAcquireRenderer(
89     std::unique_ptr<openscreen::cast::RpcMessage> message) {
90   DCHECK(message->has_integer_value());
91   DCHECK(message->integer_value() != RpcMessenger::kInvalidHandle);
92
93   remote_renderer_handle_ = message->integer_value();
94
95   // If CreateRenderer() was called before we had a valid
96   // |remote_renderer_handle_|, set it on the already created Receiver.
97   if (waiting_for_remote_handle_receiver_) {
98     // |waiting_for_remote_handle_receiver_| is the WeakPtr of the Receiver
99     // instance and should be deref in the media thread.
100     media_task_runner_->PostTask(
101         FROM_HERE, base::BindOnce(&Receiver::SetRemoteHandle,
102                                   waiting_for_remote_handle_receiver_,
103                                   remote_renderer_handle_));
104   }
105 }
106
107 void RemotingRendererFactory::OnAcquireRendererDone(int receiver_rpc_handle) {
108   // RPC_ACQUIRE_RENDERER_DONE should be sent only once.
109   //
110   // WebMediaPlayerImpl might destroy and re-create the Receiver instance
111   // several times for saving resources. However, RPC_ACQUIRE_RENDERER_DONE
112   // shouldn't be sent multiple times whenever a Receiver instance is created.
113   if (is_acquire_renderer_done_sent_)
114     return;
115
116   DVLOG(3) << __func__
117            << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle="
118            << remote_renderer_handle_ << " rpc_handle=" << receiver_rpc_handle;
119   auto rpc =
120       media::cast::CreateMessageForAcquireRendererDone(receiver_rpc_handle);
121   rpc->set_handle(remote_renderer_handle_);
122   rpc_messenger_->SendMessageToRemote(*rpc);
123
124   // Once RPC_ACQUIRE_RENDERER_DONE is sent, it implies there is no Receiver
125   // instance that is waiting the remote handle.
126   waiting_for_remote_handle_receiver_ = nullptr;
127
128   is_acquire_renderer_done_sent_ = true;
129 }
130
131 }  // namespace remoting
132 }  // namespace media