| 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 | 
|---|