Chromium Code Reviews| 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..034f1cb9f47ff45a7f8ca6317454f7744d0085bb |
| --- /dev/null |
| +++ b/media/remoting/remoting_source_impl.cc |
| @@ -0,0 +1,158 @@ |
| +// 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" |
| +#include "base/threading/thread_checker.h" |
| + |
| +namespace media { |
| + |
| +RemotingSourceImpl::RemotingSourceImpl( |
| + mojom::RemotingSourceRequest source_request, |
| + mojom::RemoterPtr remoter) |
| + : binding_(this, std::move(source_request)), remoter_(std::move(remoter)) {} |
| + |
| +RemotingSourceImpl::~RemotingSourceImpl() { |
| + if (!clients_.empty()) { |
| + UpdateAndNotifyState(RemotingSessionState::SESSION_PERMANENTLY_STOPPED); |
|
miu
2016/10/25 04:21:27
Instead of this, consider calling Shutdown() so th
xjz
2016/10/26 22:00:27
Done.
|
| + clients_.clear(); |
| + } |
| +} |
| + |
| +void RemotingSourceImpl::OnSinkAvailable() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + is_sink_available_ = true; |
| + if (state_ == RemotingSessionState::SESSION_UNAVAILABLE) |
| + UpdateAndNotifyState(RemotingSessionState::SESSION_CAN_START); |
| +} |
| + |
| +void RemotingSourceImpl::OnSinkGone() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + is_sink_available_ = false; |
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) |
| + return; |
| + if (state_ == RemotingSessionState::SESSION_CAN_START) { |
| + UpdateAndNotifyState(RemotingSessionState::SESSION_UNAVAILABLE); |
| + return; |
| + } |
| + if (state_ == RemotingSessionState::SESSION_STARTED) { |
|
miu
2016/10/25 04:21:27
Or if in the SESSION_STARTING state too, right?
xjz
2016/10/26 22:00:27
Done.
|
| + remoter_->Stop(mojom::RemotingStopReason::ROUTE_TERMINATED); |
|
miu
2016/10/25 04:21:27
Actually, you shouldn't need to call Stop() here.
xjz
2016/10/26 22:00:27
Done.
|
| + UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); |
| + } |
| +} |
| + |
| +void RemotingSourceImpl::OnStarted() { |
| + VLOG(1) << "Remoting started successively."; |
| + if (!is_sink_available_ || clients_.empty() || |
|
miu
2016/10/25 04:21:26
The "!is_sink_available_" shouldn't be needed. (Th
xjz
2016/10/26 22:00:27
Done.
|
| + state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED || |
| + state_ == RemotingSessionState::SESSION_STOPPING) { |
| + for (Client* client : clients_) |
| + client->OnStarted(false); |
| + remoter_->Stop(mojom::RemotingStopReason::ROUTE_TERMINATED); |
|
miu
2016/10/25 04:21:27
The reason should be LOCAL_PLAYBACK since either t
xjz
2016/10/26 22:00:27
Done.
|
| + if (state_ != RemotingSessionState::SESSION_PERMANENTLY_STOPPED) |
| + state_ = RemotingSessionState::SESSION_STOPPING; |
| + return; |
| + } |
| + for (Client* client : clients_) |
| + client->OnStarted(true); |
| + state_ = RemotingSessionState::SESSION_STARTED; |
| +} |
| + |
| +void RemotingSourceImpl::OnStartFailed(mojom::RemotingStartFailReason reason) { |
| + VLOG(1) << "Failed to start remoting:" << reason; |
| + for (Client* client : clients_) |
| + client->OnStarted(false); |
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) |
| + return; |
| + state_ = is_sink_available_ ? RemotingSessionState::SESSION_CAN_START |
|
miu
2016/10/25 04:21:27
This should just be "state_ = SESSION_UNAVAILABLE"
xjz
2016/10/26 22:00:27
Done.
|
| + : RemotingSessionState::SESSION_UNAVAILABLE; |
| +} |
| + |
| +void RemotingSourceImpl::OnStopped(mojom::RemotingStopReason reason) { |
| + VLOG(1) << "Remoting stopped: " << reason; |
| + if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) |
| + return; |
| + RemotingSessionState state = is_sink_available_ |
|
miu
2016/10/25 04:21:27
This should just be "state_ = SESSION_UNAVAILABLE"
xjz
2016/10/26 22:00:27
Done.
|
| + ? RemotingSessionState::SESSION_CAN_START |
| + : 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) { |
| + if (state_ == state) |
| + return; |
| + state_ = state; |
| + for (Client* client : clients_) |
| + client->OnSessionStateChanged(); |
| +} |
| + |
| +void RemotingSourceImpl::StartRemoting(Client* client) { |
| + DCHECK(clients_.find(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(clients_.find(client) != clients_.end()); |
| + |
| + VLOG(1) << "RemotingSourceImpl::StopRemoting: " << state_; |
| + |
| + if (state_ != RemotingSessionState::SESSION_STARTING && |
| + state_ != RemotingSessionState::SESSION_STARTED) |
| + return; |
| + |
| + if (state_ == RemotingSessionState::SESSION_STARTED) |
| + remoter_->Stop(mojom::RemotingStopReason::LOCAL_PLAYBACK); |
| + UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); |
| +} |
| + |
| +void RemotingSourceImpl::AddClient(Client* client) { |
| + if (clients_.find(client) != clients_.end()) |
| + return; |
| + clients_.insert(client); |
| + client->OnSessionStateChanged(); |
| +} |
| + |
| +void RemotingSourceImpl::RemoveClient(Client* client) { |
| + if (clients_.find(client) == clients_.end()) |
| + return; |
| + clients_.erase(client); |
| + if (clients_.empty() && state_ == RemotingSessionState::SESSION_STARTED) { |
|
miu
2016/10/25 04:21:27
Or if in the SESSION_STARTING state too, right?
xjz
2016/10/26 22:00:27
My original thought was to call Stop() in OnStarte
|
| + remoter_->Stop(mojom::RemotingStopReason::SOURCE_GONE); |
| + state_ = RemotingSessionState::SESSION_STOPPING; |
| + } |
| +} |
| + |
| +void RemotingSourceImpl::ShutDown() { |
| + if (state_ == RemotingSessionState::SESSION_STARTED) |
|
miu
2016/10/25 04:21:27
ditto: We want to call Stop() if SESSION_STARTING.
xjz
2016/10/26 22:00:27
Done.
|
| + remoter_->Stop(mojom::RemotingStopReason::UNEXPECTED_FAILURE); |
| + UpdateAndNotifyState(RemotingSessionState::SESSION_PERMANENTLY_STOPPED); |
| +} |
| + |
| +} // namespace media |