| Index: media/remoting/remoting_source_impl.cc
|
| diff --git a/media/remoting/remoting_source_impl.cc b/media/remoting/remoting_source_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6facc46316b531b7135283850caa6fe1e33491cf
|
| --- /dev/null
|
| +++ b/media/remoting/remoting_source_impl.cc
|
| @@ -0,0 +1,172 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "media/remoting/remoting_source_impl.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/logging.h"
|
| +
|
| +namespace media {
|
| +
|
| +RemotingSourceImpl::RemotingSourceImpl(
|
| + mojom::RemotingSourceRequest source_request,
|
| + mojom::RemoterPtr remoter)
|
| + : binding_(this, std::move(source_request)), remoter_(std::move(remoter)) {}
|
| +
|
| +RemotingSourceImpl::~RemotingSourceImpl() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (!clients_.empty()) {
|
| + ShutDown();
|
| + clients_.clear();
|
| + }
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnSinkAvailable() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (state_ == RemotingSessionState::SESSION_UNAVAILABLE)
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_CAN_START);
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnSinkGone() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED)
|
| + return;
|
| + if (state_ == RemotingSessionState::SESSION_CAN_START) {
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_UNAVAILABLE);
|
| + return;
|
| + }
|
| + if (state_ == RemotingSessionState::SESSION_STARTED ||
|
| + state_ == RemotingSessionState::SESSION_STARTING) {
|
| + VLOG(1) << "Sink is gone in a remoting session.";
|
| + // Remoting is being stopped by Remoter.
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING);
|
| + }
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnStarted() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + VLOG(1) << "Remoting started successively.";
|
| + if (clients_.empty() ||
|
| + state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED ||
|
| + state_ == RemotingSessionState::SESSION_STOPPING) {
|
| + for (Client* client : clients_)
|
| + client->OnStarted(false);
|
| + return;
|
| + }
|
| + for (Client* client : clients_)
|
| + client->OnStarted(true);
|
| + state_ = RemotingSessionState::SESSION_STARTED;
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnStartFailed(mojom::RemotingStartFailReason reason) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + VLOG(1) << "Failed to start remoting:" << reason;
|
| + for (Client* client : clients_)
|
| + client->OnStarted(false);
|
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED)
|
| + return;
|
| + state_ = RemotingSessionState::SESSION_UNAVAILABLE;
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnStopped(mojom::RemotingStopReason reason) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + VLOG(1) << "Remoting stopped: " << reason;
|
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED)
|
| + return;
|
| + RemotingSessionState state = RemotingSessionState::SESSION_UNAVAILABLE;
|
| + UpdateAndNotifyState(state);
|
| +}
|
| +
|
| +void RemotingSourceImpl::OnMessageFromSink(
|
| + const std::vector<uint8_t>& message) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + // TODO(xjz): Merge with Eric's CL to handle the RPC messages here.
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void RemotingSourceImpl::UpdateAndNotifyState(RemotingSessionState state) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (state_ == state)
|
| + return;
|
| + state_ = state;
|
| + for (Client* client : clients_)
|
| + client->OnSessionStateChanged();
|
| +}
|
| +
|
| +void RemotingSourceImpl::StartRemoting(Client* client) {
|
| + DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end());
|
| +
|
| + switch (state_) {
|
| + case SESSION_CAN_START:
|
| + remoter_->Start();
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_STARTING);
|
| + break;
|
| + case SESSION_STARTING:
|
| + break;
|
| + case SESSION_STARTED:
|
| + client->OnStarted(true);
|
| + break;
|
| + case SESSION_STOPPING:
|
| + case SESSION_UNAVAILABLE:
|
| + case SESSION_PERMANENTLY_STOPPED:
|
| + client->OnStarted(false);
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void RemotingSourceImpl::StopRemoting(Client* client) {
|
| + DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end());
|
| +
|
| + VLOG(1) << "RemotingSourceImpl::StopRemoting: " << state_;
|
| +
|
| + if (state_ != RemotingSessionState::SESSION_STARTING &&
|
| + state_ != RemotingSessionState::SESSION_STARTED)
|
| + return;
|
| +
|
| + remoter_->Stop(mojom::RemotingStopReason::LOCAL_PLAYBACK);
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING);
|
| +}
|
| +
|
| +void RemotingSourceImpl::AddClient(Client* client) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (std::find(clients_.begin(), clients_.end(), client) != clients_.end())
|
| + return;
|
| + clients_.push_back(client);
|
| + client->OnSessionStateChanged();
|
| +}
|
| +
|
| +void RemotingSourceImpl::RemoveClient(Client* client) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + auto it = std::find(clients_.begin(), clients_.end(), client);
|
| + if (it == clients_.end())
|
| + return;
|
| +
|
| + clients_.erase(it);
|
| + if (clients_.empty() && (state_ == RemotingSessionState::SESSION_STARTED ||
|
| + state_ == RemotingSessionState::SESSION_STARTING)) {
|
| + remoter_->Stop(mojom::RemotingStopReason::SOURCE_GONE);
|
| + state_ = RemotingSessionState::SESSION_STOPPING;
|
| + }
|
| +}
|
| +
|
| +void RemotingSourceImpl::ShutDown() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (state_ == RemotingSessionState::SESSION_STARTED ||
|
| + state_ == RemotingSessionState::SESSION_STARTING)
|
| + remoter_->Stop(mojom::RemotingStopReason::UNEXPECTED_FAILURE);
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_PERMANENTLY_STOPPED);
|
| +}
|
| +
|
| +} // namespace media
|
|
|