OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/remoting/remoting_source_impl.h" | 5 #include "media/remoting/shared_session.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/remoting/rpc/proto_utils.h" | 9 #include "media/remoting/proto_utils.h" |
10 | 10 |
11 namespace media { | 11 namespace media { |
| 12 namespace remoting { |
12 | 13 |
13 RemotingSourceImpl::RemotingSourceImpl( | 14 SharedSession::SharedSession(mojom::RemotingSourceRequest source_request, |
14 mojom::RemotingSourceRequest source_request, | 15 mojom::RemoterPtr remoter) |
15 mojom::RemoterPtr remoter) | 16 : rpc_broker_(base::Bind(&SharedSession::SendMessageToSink, |
16 : rpc_broker_(base::Bind(&RemotingSourceImpl::SendMessageToSink, | |
17 base::Unretained(this))), | 17 base::Unretained(this))), |
18 binding_(this, std::move(source_request)), | 18 binding_(this, std::move(source_request)), |
19 remoter_(std::move(remoter)) { | 19 remoter_(std::move(remoter)) { |
20 DCHECK(remoter_); | 20 DCHECK(remoter_); |
21 } | 21 } |
22 | 22 |
23 RemotingSourceImpl::~RemotingSourceImpl() { | 23 SharedSession::~SharedSession() { |
24 DCHECK(thread_checker_.CalledOnValidThread()); | 24 DCHECK(thread_checker_.CalledOnValidThread()); |
25 | 25 |
26 if (!clients_.empty()) { | 26 if (!clients_.empty()) { |
27 Shutdown(); | 27 Shutdown(); |
28 clients_.clear(); | 28 clients_.clear(); |
29 } | 29 } |
30 } | 30 } |
31 | 31 |
32 void RemotingSourceImpl::OnSinkAvailable( | 32 void SharedSession::OnSinkAvailable( |
33 mojom::RemotingSinkCapabilities capabilities) { | 33 mojom::RemotingSinkCapabilities capabilities) { |
34 DCHECK(thread_checker_.CalledOnValidThread()); | 34 DCHECK(thread_checker_.CalledOnValidThread()); |
35 | 35 |
36 if (capabilities == mojom::RemotingSinkCapabilities::NONE) { | 36 if (capabilities == mojom::RemotingSinkCapabilities::NONE) { |
37 OnSinkGone(); | 37 OnSinkGone(); |
38 return; | 38 return; |
39 } | 39 } |
40 sink_capabilities_ = capabilities; | 40 sink_capabilities_ = capabilities; |
41 if (state_ == RemotingSessionState::SESSION_UNAVAILABLE) | 41 if (state_ == SESSION_UNAVAILABLE) |
42 UpdateAndNotifyState(RemotingSessionState::SESSION_CAN_START); | 42 UpdateAndNotifyState(SESSION_CAN_START); |
43 } | 43 } |
44 | 44 |
45 void RemotingSourceImpl::OnSinkGone() { | 45 void SharedSession::OnSinkGone() { |
46 DCHECK(thread_checker_.CalledOnValidThread()); | 46 DCHECK(thread_checker_.CalledOnValidThread()); |
47 | 47 |
48 sink_capabilities_ = mojom::RemotingSinkCapabilities::NONE; | 48 sink_capabilities_ = mojom::RemotingSinkCapabilities::NONE; |
49 | 49 |
50 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | 50 if (state_ == SESSION_PERMANENTLY_STOPPED) |
51 return; | 51 return; |
52 if (state_ == RemotingSessionState::SESSION_CAN_START) { | 52 if (state_ == SESSION_CAN_START) { |
53 UpdateAndNotifyState(RemotingSessionState::SESSION_UNAVAILABLE); | 53 UpdateAndNotifyState(SESSION_UNAVAILABLE); |
54 return; | 54 return; |
55 } | 55 } |
56 if (state_ == RemotingSessionState::SESSION_STARTED || | 56 if (state_ == SESSION_STARTED || state_ == SESSION_STARTING) { |
57 state_ == RemotingSessionState::SESSION_STARTING) { | |
58 VLOG(1) << "Sink is gone in a remoting session."; | 57 VLOG(1) << "Sink is gone in a remoting session."; |
59 // Remoting is being stopped by Remoter. | 58 // Remoting is being stopped by Remoter. |
60 UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); | 59 UpdateAndNotifyState(SESSION_STOPPING); |
61 } | 60 } |
62 } | 61 } |
63 | 62 |
64 void RemotingSourceImpl::OnStarted() { | 63 void SharedSession::OnStarted() { |
65 DCHECK(thread_checker_.CalledOnValidThread()); | 64 DCHECK(thread_checker_.CalledOnValidThread()); |
66 | 65 |
67 VLOG(1) << "Remoting started successively."; | 66 VLOG(1) << "Remoting started successively."; |
68 if (clients_.empty() || | 67 if (clients_.empty() || state_ == SESSION_PERMANENTLY_STOPPED || |
69 state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED || | 68 state_ == SESSION_STOPPING) { |
70 state_ == RemotingSessionState::SESSION_STOPPING) { | |
71 for (Client* client : clients_) | 69 for (Client* client : clients_) |
72 client->OnStarted(false); | 70 client->OnStarted(false); |
73 return; | 71 return; |
74 } | 72 } |
75 for (Client* client : clients_) | 73 for (Client* client : clients_) |
76 client->OnStarted(true); | 74 client->OnStarted(true); |
77 state_ = RemotingSessionState::SESSION_STARTED; | 75 state_ = SESSION_STARTED; |
78 } | 76 } |
79 | 77 |
80 void RemotingSourceImpl::OnStartFailed(mojom::RemotingStartFailReason reason) { | 78 void SharedSession::OnStartFailed(mojom::RemotingStartFailReason reason) { |
81 DCHECK(thread_checker_.CalledOnValidThread()); | 79 DCHECK(thread_checker_.CalledOnValidThread()); |
82 | 80 |
83 VLOG(1) << "Failed to start remoting:" << reason; | 81 VLOG(1) << "Failed to start remoting:" << reason; |
84 for (Client* client : clients_) | 82 for (Client* client : clients_) |
85 client->OnStarted(false); | 83 client->OnStarted(false); |
86 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | 84 if (state_ == SESSION_PERMANENTLY_STOPPED) |
87 return; | 85 return; |
88 state_ = RemotingSessionState::SESSION_UNAVAILABLE; | 86 state_ = SESSION_UNAVAILABLE; |
89 } | 87 } |
90 | 88 |
91 void RemotingSourceImpl::OnStopped(mojom::RemotingStopReason reason) { | 89 void SharedSession::OnStopped(mojom::RemotingStopReason reason) { |
92 DCHECK(thread_checker_.CalledOnValidThread()); | 90 DCHECK(thread_checker_.CalledOnValidThread()); |
93 | 91 |
94 VLOG(1) << "Remoting stopped: " << reason; | 92 VLOG(1) << "Remoting stopped: " << reason; |
95 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | 93 if (state_ == SESSION_PERMANENTLY_STOPPED) |
96 return; | 94 return; |
97 RemotingSessionState state = RemotingSessionState::SESSION_UNAVAILABLE; | 95 UpdateAndNotifyState(SESSION_UNAVAILABLE); |
98 UpdateAndNotifyState(state); | |
99 } | 96 } |
100 | 97 |
101 void RemotingSourceImpl::OnMessageFromSink( | 98 void SharedSession::OnMessageFromSink(const std::vector<uint8_t>& message) { |
102 const std::vector<uint8_t>& message) { | |
103 DCHECK(thread_checker_.CalledOnValidThread()); | 99 DCHECK(thread_checker_.CalledOnValidThread()); |
104 | 100 |
105 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 101 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
106 if (!rpc->ParseFromArray(message.data(), message.size())) { | 102 if (!rpc->ParseFromArray(message.data(), message.size())) { |
107 LOG(ERROR) << "corrupted Rpc message"; | 103 VLOG(1) << "corrupted Rpc message"; |
108 Shutdown(); | 104 Shutdown(); |
109 return; | 105 return; |
110 } | 106 } |
111 rpc_broker_.ProcessMessageFromRemote(std::move(rpc)); | 107 rpc_broker_.ProcessMessageFromRemote(std::move(rpc)); |
112 } | 108 } |
113 | 109 |
114 void RemotingSourceImpl::UpdateAndNotifyState(RemotingSessionState state) { | 110 void SharedSession::UpdateAndNotifyState(SessionState state) { |
115 DCHECK(thread_checker_.CalledOnValidThread()); | 111 DCHECK(thread_checker_.CalledOnValidThread()); |
116 | 112 |
117 if (state_ == state) | 113 if (state_ == state) |
118 return; | 114 return; |
119 state_ = state; | 115 state_ = state; |
120 for (Client* client : clients_) | 116 for (Client* client : clients_) |
121 client->OnSessionStateChanged(); | 117 client->OnSessionStateChanged(); |
122 } | 118 } |
123 | 119 |
124 void RemotingSourceImpl::StartRemoting(Client* client) { | 120 void SharedSession::StartRemoting(Client* client) { |
125 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); | 121 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); |
126 | 122 |
127 switch (state_) { | 123 switch (state_) { |
128 case SESSION_CAN_START: | 124 case SESSION_CAN_START: |
129 remoter_->Start(); | 125 remoter_->Start(); |
130 UpdateAndNotifyState(RemotingSessionState::SESSION_STARTING); | 126 UpdateAndNotifyState(SESSION_STARTING); |
131 break; | 127 break; |
132 case SESSION_STARTING: | 128 case SESSION_STARTING: |
133 break; | 129 break; |
134 case SESSION_STARTED: | 130 case SESSION_STARTED: |
135 client->OnStarted(true); | 131 client->OnStarted(true); |
136 break; | 132 break; |
137 case SESSION_STOPPING: | 133 case SESSION_STOPPING: |
138 case SESSION_UNAVAILABLE: | 134 case SESSION_UNAVAILABLE: |
139 case SESSION_PERMANENTLY_STOPPED: | 135 case SESSION_PERMANENTLY_STOPPED: |
140 client->OnStarted(false); | 136 client->OnStarted(false); |
141 break; | 137 break; |
142 } | 138 } |
143 } | 139 } |
144 | 140 |
145 void RemotingSourceImpl::StopRemoting(Client* client) { | 141 void SharedSession::StopRemoting(Client* client) { |
146 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); | 142 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); |
147 | 143 |
148 VLOG(1) << "RemotingSourceImpl::StopRemoting: " << state_; | 144 VLOG(1) << "SharedSession::StopRemoting: " << state_; |
149 | 145 |
150 if (state_ != RemotingSessionState::SESSION_STARTING && | 146 if (state_ != SESSION_STARTING && state_ != SESSION_STARTED) |
151 state_ != RemotingSessionState::SESSION_STARTED) | |
152 return; | 147 return; |
153 | 148 |
154 remoter_->Stop(mojom::RemotingStopReason::LOCAL_PLAYBACK); | 149 remoter_->Stop(mojom::RemotingStopReason::LOCAL_PLAYBACK); |
155 UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); | 150 UpdateAndNotifyState(SESSION_STOPPING); |
156 } | 151 } |
157 | 152 |
158 void RemotingSourceImpl::AddClient(Client* client) { | 153 void SharedSession::AddClient(Client* client) { |
159 DCHECK(thread_checker_.CalledOnValidThread()); | 154 DCHECK(thread_checker_.CalledOnValidThread()); |
160 DCHECK(std::find(clients_.begin(), clients_.end(), client) == clients_.end()); | 155 DCHECK(std::find(clients_.begin(), clients_.end(), client) == clients_.end()); |
161 | 156 |
162 clients_.push_back(client); | 157 clients_.push_back(client); |
163 } | 158 } |
164 | 159 |
165 void RemotingSourceImpl::RemoveClient(Client* client) { | 160 void SharedSession::RemoveClient(Client* client) { |
166 DCHECK(thread_checker_.CalledOnValidThread()); | 161 DCHECK(thread_checker_.CalledOnValidThread()); |
167 | 162 |
168 auto it = std::find(clients_.begin(), clients_.end(), client); | 163 auto it = std::find(clients_.begin(), clients_.end(), client); |
169 DCHECK(it != clients_.end()); | 164 DCHECK(it != clients_.end()); |
170 | 165 |
171 clients_.erase(it); | 166 clients_.erase(it); |
172 if (clients_.empty() && (state_ == RemotingSessionState::SESSION_STARTED || | 167 if (clients_.empty() && |
173 state_ == RemotingSessionState::SESSION_STARTING)) { | 168 (state_ == SESSION_STARTED || state_ == SESSION_STARTING)) { |
174 remoter_->Stop(mojom::RemotingStopReason::SOURCE_GONE); | 169 remoter_->Stop(mojom::RemotingStopReason::SOURCE_GONE); |
175 state_ = RemotingSessionState::SESSION_STOPPING; | 170 state_ = SESSION_STOPPING; |
176 } | 171 } |
177 } | 172 } |
178 | 173 |
179 void RemotingSourceImpl::Shutdown() { | 174 void SharedSession::Shutdown() { |
180 DCHECK(thread_checker_.CalledOnValidThread()); | 175 DCHECK(thread_checker_.CalledOnValidThread()); |
181 | 176 |
182 if (state_ == RemotingSessionState::SESSION_STARTED || | 177 if (state_ == SESSION_STARTED || state_ == SESSION_STARTING) |
183 state_ == RemotingSessionState::SESSION_STARTING) | |
184 remoter_->Stop(mojom::RemotingStopReason::UNEXPECTED_FAILURE); | 178 remoter_->Stop(mojom::RemotingStopReason::UNEXPECTED_FAILURE); |
185 UpdateAndNotifyState(RemotingSessionState::SESSION_PERMANENTLY_STOPPED); | 179 UpdateAndNotifyState(SESSION_PERMANENTLY_STOPPED); |
186 } | 180 } |
187 | 181 |
188 void RemotingSourceImpl::StartDataPipe( | 182 void SharedSession::StartDataPipe( |
189 std::unique_ptr<mojo::DataPipe> audio_data_pipe, | 183 std::unique_ptr<mojo::DataPipe> audio_data_pipe, |
190 std::unique_ptr<mojo::DataPipe> video_data_pipe, | 184 std::unique_ptr<mojo::DataPipe> video_data_pipe, |
191 const DataPipeStartCallback& done_callback) { | 185 const DataPipeStartCallback& done_callback) { |
192 DCHECK(thread_checker_.CalledOnValidThread()); | 186 DCHECK(thread_checker_.CalledOnValidThread()); |
193 DCHECK(!done_callback.is_null()); | 187 DCHECK(!done_callback.is_null()); |
194 | 188 |
195 bool audio = audio_data_pipe != nullptr; | 189 bool audio = audio_data_pipe != nullptr; |
196 bool video = video_data_pipe != nullptr; | 190 bool video = video_data_pipe != nullptr; |
197 if (!audio && !video) { | 191 if (!audio && !video) { |
198 LOG(ERROR) << "No audio and video to establish data pipe"; | 192 LOG(ERROR) << "No audio nor video to establish data pipe"; |
199 done_callback.Run(mojom::RemotingDataStreamSenderPtrInfo(), | 193 done_callback.Run(mojom::RemotingDataStreamSenderPtrInfo(), |
200 mojom::RemotingDataStreamSenderPtrInfo(), | 194 mojom::RemotingDataStreamSenderPtrInfo(), |
201 mojo::ScopedDataPipeProducerHandle(), | 195 mojo::ScopedDataPipeProducerHandle(), |
202 mojo::ScopedDataPipeProducerHandle()); | 196 mojo::ScopedDataPipeProducerHandle()); |
203 return; | 197 return; |
204 } | 198 } |
205 mojom::RemotingDataStreamSenderPtr audio_stream_sender; | 199 mojom::RemotingDataStreamSenderPtr audio_stream_sender; |
206 mojom::RemotingDataStreamSenderPtr video_stream_sender; | 200 mojom::RemotingDataStreamSenderPtr video_stream_sender; |
207 remoter_->StartDataStreams( | 201 remoter_->StartDataStreams(audio ? std::move(audio_data_pipe->consumer_handle) |
208 audio ? std::move(audio_data_pipe->consumer_handle) | 202 : mojo::ScopedDataPipeConsumerHandle(), |
209 : mojo::ScopedDataPipeConsumerHandle(), | 203 video ? std::move(video_data_pipe->consumer_handle) |
210 video ? std::move(video_data_pipe->consumer_handle) | 204 : mojo::ScopedDataPipeConsumerHandle(), |
211 : mojo::ScopedDataPipeConsumerHandle(), | 205 audio ? mojo::MakeRequest(&audio_stream_sender) |
212 audio ? mojo::MakeRequest(&audio_stream_sender) | 206 : mojom::RemotingDataStreamSenderRequest(), |
213 : media::mojom::RemotingDataStreamSenderRequest(), | 207 video ? mojo::MakeRequest(&video_stream_sender) |
214 video ? mojo::MakeRequest(&video_stream_sender) | 208 : mojom::RemotingDataStreamSenderRequest()); |
215 : media::mojom::RemotingDataStreamSenderRequest()); | |
216 done_callback.Run(audio_stream_sender.PassInterface(), | 209 done_callback.Run(audio_stream_sender.PassInterface(), |
217 video_stream_sender.PassInterface(), | 210 video_stream_sender.PassInterface(), |
218 audio ? std::move(audio_data_pipe->producer_handle) | 211 audio ? std::move(audio_data_pipe->producer_handle) |
219 : mojo::ScopedDataPipeProducerHandle(), | 212 : mojo::ScopedDataPipeProducerHandle(), |
220 video ? std::move(video_data_pipe->producer_handle) | 213 video ? std::move(video_data_pipe->producer_handle) |
221 : mojo::ScopedDataPipeProducerHandle()); | 214 : mojo::ScopedDataPipeProducerHandle()); |
222 } | 215 } |
223 | 216 |
224 remoting::RpcBroker* RemotingSourceImpl::GetRpcBroker() const { | 217 void SharedSession::SendMessageToSink( |
225 DCHECK(thread_checker_.CalledOnValidThread()); | |
226 // TODO(xjz): Fix the const-correctness. | |
227 return const_cast<remoting::RpcBroker*>(&rpc_broker_); | |
228 } | |
229 | |
230 void RemotingSourceImpl::SendMessageToSink( | |
231 std::unique_ptr<std::vector<uint8_t>> message) { | 218 std::unique_ptr<std::vector<uint8_t>> message) { |
232 DCHECK(thread_checker_.CalledOnValidThread()); | 219 DCHECK(thread_checker_.CalledOnValidThread()); |
233 remoter_->SendMessageToSink(*message); | 220 remoter_->SendMessageToSink(*message); |
234 } | 221 } |
235 | 222 |
| 223 } // namespace remoting |
236 } // namespace media | 224 } // namespace media |
OLD | NEW |