Commit e2c48d9b authored by Fabrice de Gans-Riberi's avatar Fabrice de Gans-Riberi Committed by Commit Bot

[fuchsia] Transition Cast Streaming to use Cast MessagePorts

Bug: 1147941
Change-Id: Id88d06e4be726d745ced8a0944b0cfbf9241d42a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2532861
Commit-Queue: Fabrice de Gans-Riberi <fdegans@chromium.org>
Reviewed-by: default avatarKevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826908}
parent c3aed755
...@@ -9,7 +9,6 @@ source_set("cast_streaming") { ...@@ -9,7 +9,6 @@ source_set("cast_streaming") {
"//base", "//base",
"//components/openscreen_platform", "//components/openscreen_platform",
"//components/openscreen_platform:openscreen_platform_network_service", "//components/openscreen_platform:openscreen_platform_network_service",
"//fuchsia/base",
"//media", "//media",
"//media/mojo/common", "//media/mojo/common",
"//media/mojo/mojom", "//media/mojo/mojom",
...@@ -20,6 +19,7 @@ source_set("cast_streaming") { ...@@ -20,6 +19,7 @@ source_set("cast_streaming") {
"//third_party/openscreen/src/platform:api", "//third_party/openscreen/src/platform:api",
"//third_party/openscreen/src/util", "//third_party/openscreen/src/util",
] ]
public_deps = [ "//components/cast/message_port" ]
visibility = [ "//fuchsia/engine/*" ] visibility = [ "//fuchsia/engine/*" ]
public = [ public = [
"public/cast_streaming.h", "public/cast_streaming.h",
......
include_rules = [ include_rules = [
"+components/cast/message_port",
"+components/openscreen_platform", "+components/openscreen_platform",
"+media/base", "+media/base",
"+media/mojo", "+media/mojo",
......
...@@ -4,12 +4,10 @@ ...@@ -4,12 +4,10 @@
#include "fuchsia/cast_streaming/cast_message_port_impl.h" #include "fuchsia/cast_streaming/cast_message_port_impl.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/values.h" #include "base/values.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "third_party/openscreen/src/platform/base/error.h" #include "third_party/openscreen/src/platform/base/error.h"
namespace cast_streaming { namespace cast_streaming {
...@@ -50,26 +48,13 @@ const char kInitialConnectMessage[] = R"( ...@@ -50,26 +48,13 @@ const char kInitialConnectMessage[] = R"(
} }
)"; )";
// Upper limit for pending FIDL messages. Messages are going to be pending as
// long as the other end of the MessagePort does not acknowledge the latest
// message. This is to prevent the queue from being overrun in case the other
// end of the FIDL MessagePort is misbehaving.
// This should cover the largest burst of messages from the Open Screen
// implementation.
constexpr size_t kMaxPendingFidlMessages = 10;
// Extracts |buffer| data into |sender_id|, |message_namespace| and |message|. // Extracts |buffer| data into |sender_id|, |message_namespace| and |message|.
// Returns true on success. // Returns true on success.
bool ParseMessageBuffer(const fuchsia::mem::Buffer& buffer, bool ParseMessageBuffer(base::StringPiece buffer,
std::string* sender_id, std::string* sender_id,
std::string* message_namespace, std::string* message_namespace,
std::string* message) { std::string* message) {
std::string string_buffer; base::Optional<base::Value> converted_value = base::JSONReader::Read(buffer);
if (!cr_fuchsia::StringFromMemBuffer(buffer, &string_buffer))
return false;
base::Optional<base::Value> converted_value =
base::JSONReader::Read(string_buffer);
if (!converted_value) if (!converted_value)
return false; return false;
...@@ -93,11 +78,11 @@ bool ParseMessageBuffer(const fuchsia::mem::Buffer& buffer, ...@@ -93,11 +78,11 @@ bool ParseMessageBuffer(const fuchsia::mem::Buffer& buffer,
return true; return true;
} }
// Creates a WebMessage out of the |sender_id|, |message_namespace| and // Creates a message string out of the |sender_id|, |message_namespace| and
// |message|. // |message|.
fuchsia::web::WebMessage CreateWebMessage(const std::string& sender_id, std::string CreateStringMessage(const std::string& sender_id,
const std::string& message_namespace, const std::string& message_namespace,
const std::string& message) { const std::string& message) {
base::Value value(base::Value::Type::DICTIONARY); base::Value value(base::Value::Type::DICTIONARY);
value.SetStringKey(kKeyNamespace, message_namespace); value.SetStringKey(kKeyNamespace, message_namespace);
value.SetStringKey(kKeySenderId, sender_id); value.SetStringKey(kKeySenderId, sender_id);
...@@ -105,31 +90,16 @@ fuchsia::web::WebMessage CreateWebMessage(const std::string& sender_id, ...@@ -105,31 +90,16 @@ fuchsia::web::WebMessage CreateWebMessage(const std::string& sender_id,
std::string json_message; std::string json_message;
CHECK(base::JSONWriter::Write(value, &json_message)); CHECK(base::JSONWriter::Write(value, &json_message));
return json_message;
fuchsia::mem::Buffer buffer;
buffer.size = json_message.size();
zx_status_t status = zx::vmo::create(json_message.size(), 0, &buffer.vmo);
ZX_DCHECK(status == ZX_OK, status);
status = buffer.vmo.write(json_message.data(), 0, json_message.size());
ZX_DCHECK(status == ZX_OK, status);
fuchsia::web::WebMessage web_message;
web_message.set_data(std::move(buffer));
return web_message;
} }
} // namespace } // namespace
CastMessagePortImpl::CastMessagePortImpl( CastMessagePortImpl::CastMessagePortImpl(
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request) std::unique_ptr<cast_api_bindings::MessagePort> message_port)
: message_port_binding_(this, std::move(message_port_request)) { : message_port_(std::move(message_port)) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
DCHECK(message_port_binding_.is_bound()); message_port_->SetReceiver(this);
message_port_binding_.set_error_handler([this](zx_status_t status) {
ZX_LOG(ERROR, status) << "MessagePort disconnected.";
MaybeCloseWithEpitaph(ZX_ERR_BAD_STATE);
});
// Initialize the connection with the Cast Streaming Sender. // Initialize the connection with the Cast Streaming Sender.
PostMessage(kValueSystemSenderId, kSystemNamespace, kInitialConnectMessage); PostMessage(kValueSystemSenderId, kSystemNamespace, kInitialConnectMessage);
...@@ -137,24 +107,13 @@ CastMessagePortImpl::CastMessagePortImpl( ...@@ -137,24 +107,13 @@ CastMessagePortImpl::CastMessagePortImpl(
CastMessagePortImpl::~CastMessagePortImpl() = default; CastMessagePortImpl::~CastMessagePortImpl() = default;
void CastMessagePortImpl::MaybeSendMessageToFidl() { void CastMessagePortImpl::MaybeClose() {
DVLOG(3) << __func__; if (message_port_)
if (!receive_message_callback_ || pending_fidl_messages_.empty()) message_port_.reset();
return;
receive_message_callback_(std::move(pending_fidl_messages_.front()));
receive_message_callback_ = nullptr;
pending_fidl_messages_.pop_front();
}
void CastMessagePortImpl::MaybeCloseWithEpitaph(zx_status_t epitaph) {
if (message_port_binding_.is_bound())
message_port_binding_.Close(epitaph);
if (client_) { if (client_) {
client_->OnError( client_->OnError(
openscreen::Error(openscreen::Error::Code::kCastV2CastSocketError)); openscreen::Error(openscreen::Error::Code::kCastV2CastSocketError));
} }
pending_fidl_messages_.clear();
} }
void CastMessagePortImpl::SetClient( void CastMessagePortImpl::SetClient(
...@@ -164,12 +123,12 @@ void CastMessagePortImpl::SetClient( ...@@ -164,12 +123,12 @@ void CastMessagePortImpl::SetClient(
DCHECK_NE(!client_, !client); DCHECK_NE(!client_, !client);
client_ = client; client_ = client;
if (!client_) if (!client_)
MaybeCloseWithEpitaph(ZX_OK); MaybeClose();
} }
void CastMessagePortImpl::ResetClient() { void CastMessagePortImpl::ResetClient() {
client_ = nullptr; client_ = nullptr;
MaybeCloseWithEpitaph(ZX_OK); MaybeClose();
} }
void CastMessagePortImpl::SendInjectResponse(const std::string& sender_id, void CastMessagePortImpl::SendInjectResponse(const std::string& sender_id,
...@@ -222,42 +181,41 @@ void CastMessagePortImpl::PostMessage(const std::string& sender_id, ...@@ -222,42 +181,41 @@ void CastMessagePortImpl::PostMessage(const std::string& sender_id,
const std::string& message_namespace, const std::string& message_namespace,
const std::string& message) { const std::string& message) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
if (!message_port_binding_.is_bound()) if (!message_port_)
return;
if (pending_fidl_messages_.size() > kMaxPendingFidlMessages) {
LOG(ERROR) << "Too many buffered Open Screen messages.";
MaybeCloseWithEpitaph(ZX_ERR_BAD_STATE);
return; return;
}
DVLOG(3) << "Received Open Screen message. SenderId: " << sender_id DVLOG(3) << "Received Open Screen message. SenderId: " << sender_id
<< ". Namespace: " << message_namespace << ". Message: " << message; << ". Namespace: " << message_namespace << ". Message: " << message;
message_port_->PostMessage(
pending_fidl_messages_.push_back( CreateStringMessage(sender_id, message_namespace, message));
CreateWebMessage(sender_id, message_namespace, message));
MaybeSendMessageToFidl();
} }
void CastMessagePortImpl::PostMessage( bool CastMessagePortImpl::OnMessage(
fuchsia::web::WebMessage message, base::StringPiece message,
fuchsia::web::MessagePort::PostMessageCallback callback) { std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> ports) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
// If |client_| was cleared, the binding should have been closed. // If |client_| was cleared, |message_port_| should have been reset.
DCHECK(client_); DCHECK(client_);
if (!ports.empty()) {
// We should never receive any ports for Cast Streaming.
LOG(ERROR) << "Received ports on Cast Streaming MessagePort.";
MaybeClose();
return false;
}
std::string sender_id; std::string sender_id;
std::string message_namespace; std::string message_namespace;
std::string str_message; std::string str_message;
if (!ParseMessageBuffer(message.data(), &sender_id, &message_namespace, if (!ParseMessageBuffer(message, &sender_id, &message_namespace,
&str_message)) { &str_message)) {
LOG(ERROR) << "Received bad message."; LOG(ERROR) << "Received bad message.";
client_->OnError( client_->OnError(
openscreen::Error(openscreen::Error::Code::kCastV2InvalidMessage)); openscreen::Error(openscreen::Error::Code::kCastV2InvalidMessage));
return; return false;
} }
DVLOG(3) << "Received FIDL message. SenderId: " << sender_id DVLOG(3) << "Received Cast message. SenderId: " << sender_id
<< ". Namespace: " << message_namespace << ". Namespace: " << message_namespace
<< ". Message: " << str_message; << ". Message: " << str_message;
...@@ -274,22 +232,12 @@ void CastMessagePortImpl::PostMessage( ...@@ -274,22 +232,12 @@ void CastMessagePortImpl::PostMessage(
<< ", message=" << str_message; << ", message=" << str_message;
} }
// Acknowledge the message and unblock the receipt of another. return true;
fuchsia::web::MessagePort_PostMessage_Result result;
result.set_response(fuchsia::web::MessagePort_PostMessage_Response());
callback(std::move(result));
} }
void CastMessagePortImpl::ReceiveMessage( void CastMessagePortImpl::OnPipeError() {
fuchsia::web::MessagePort::ReceiveMessageCallback callback) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
if (receive_message_callback_) { MaybeClose();
MaybeCloseWithEpitaph(ZX_ERR_BAD_STATE);
return;
}
receive_message_callback_ = std::move(callback);
MaybeSendMessageToFidl();
} }
} // namespace cast_streaming } // namespace cast_streaming
...@@ -5,21 +5,18 @@ ...@@ -5,21 +5,18 @@
#ifndef FUCHSIA_CAST_STREAMING_CAST_MESSAGE_PORT_IMPL_H_ #ifndef FUCHSIA_CAST_STREAMING_CAST_MESSAGE_PORT_IMPL_H_
#define FUCHSIA_CAST_STREAMING_CAST_MESSAGE_PORT_IMPL_H_ #define FUCHSIA_CAST_STREAMING_CAST_MESSAGE_PORT_IMPL_H_
#include <fuchsia/web/cpp/fidl.h> #include "components/cast/message_port/message_port.h"
#include <lib/fidl/cpp/binding.h>
#include "base/containers/circular_deque.h"
#include "third_party/openscreen/src/cast/common/public/message_port.h" #include "third_party/openscreen/src/cast/common/public/message_port.h"
namespace cast_streaming { namespace cast_streaming {
// Wrapper for a fuchsia.web.MessagePort that provides an Open Screen // Wrapper for a cast MessagePort that provides an Open Screen MessagePort
// MessagePort implementation. // implementation.
class CastMessagePortImpl : public openscreen::cast::MessagePort, class CastMessagePortImpl : public openscreen::cast::MessagePort,
public fuchsia::web::MessagePort { public cast_api_bindings::MessagePort::Receiver {
public: public:
explicit CastMessagePortImpl( explicit CastMessagePortImpl(
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request); std::unique_ptr<cast_api_bindings::MessagePort> message_port);
~CastMessagePortImpl() final; ~CastMessagePortImpl() final;
CastMessagePortImpl(const CastMessagePortImpl&) = delete; CastMessagePortImpl(const CastMessagePortImpl&) = delete;
...@@ -33,34 +30,23 @@ class CastMessagePortImpl : public openscreen::cast::MessagePort, ...@@ -33,34 +30,23 @@ class CastMessagePortImpl : public openscreen::cast::MessagePort,
const std::string& message) final; const std::string& message) final;
private: private:
// Sends one message in |pending_fidl_messages_| if // Resets |message_port_| if it is open and signals an error to |client_| if
// |receive_message_callback_| is set. // |client_| is set.
void MaybeSendMessageToFidl(); void MaybeClose();
// Closes the fuchsia.web.MessagePort connection and cleans up internal state.
// * Closes |message_port_binding_| with |epitaph| if it is still open.
// * Signals an error to |client_| if |client_| is set.
// * Empties |pending_fidl_messages_|.
void MaybeCloseWithEpitaph(zx_status_t epitaph);
// Returns a "not supported" error message to the sender for messages from // Returns a "not supported" error message to the sender for messages from
// the inject namespace. // the inject namespace.
void SendInjectResponse(const std::string& sender_id, void SendInjectResponse(const std::string& sender_id,
const std::string& message); const std::string& message);
// fuchsia::web::MessagePort implementation. // cast_api_bindings::MessagePort::Receiver implementation.
void PostMessage(fuchsia::web::WebMessage message, bool OnMessage(
PostMessageCallback callback) final; base::StringPiece message,
void ReceiveMessage(ReceiveMessageCallback callback) final; std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> ports) final;
void OnPipeError() final;
Client* client_ = nullptr; Client* client_ = nullptr;
std::unique_ptr<cast_api_bindings::MessagePort> message_port_;
// Holds WebMessages waiting to be sent over FIDL.
base::circular_deque<fuchsia::web::WebMessage> pending_fidl_messages_;
ReceiveMessageCallback receive_message_callback_;
fidl::Binding<fuchsia::web::MessagePort> message_port_binding_;
}; };
} // namespace cast_streaming } // namespace cast_streaming
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "fuchsia/cast_streaming/public/cast_streaming_session.h" #include "fuchsia/cast_streaming/public/cast_streaming_session.h"
#include <lib/zx/time.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/notreached.h" #include "base/notreached.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -109,13 +107,12 @@ void CastStreamingSession::SetNetworkContextGetter( ...@@ -109,13 +107,12 @@ void CastStreamingSession::SetNetworkContextGetter(
class CastStreamingSession::Internal class CastStreamingSession::Internal
: public openscreen::cast::ReceiverSession::Client { : public openscreen::cast::ReceiverSession::Client {
public: public:
Internal( Internal(CastStreamingSession::Client* client,
CastStreamingSession::Client* client, std::unique_ptr<cast_api_bindings::MessagePort> message_port,
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request, scoped_refptr<base::SequencedTaskRunner> task_runner)
scoped_refptr<base::SequencedTaskRunner> task_runner)
: task_runner_(task_runner), : task_runner_(task_runner),
environment_(&openscreen::Clock::now, &task_runner_), environment_(&openscreen::Clock::now, &task_runner_),
cast_message_port_impl_(std::move(message_port_request)), cast_message_port_impl_(std::move(message_port)),
client_(client) { client_(client) {
DCHECK(task_runner); DCHECK(task_runner);
DCHECK(client_); DCHECK(client_);
...@@ -336,12 +333,12 @@ CastStreamingSession::~CastStreamingSession() = default; ...@@ -336,12 +333,12 @@ CastStreamingSession::~CastStreamingSession() = default;
void CastStreamingSession::Start( void CastStreamingSession::Start(
Client* client, Client* client,
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request, std::unique_ptr<cast_api_bindings::MessagePort> message_port,
scoped_refptr<base::SequencedTaskRunner> task_runner) { scoped_refptr<base::SequencedTaskRunner> task_runner) {
DCHECK(client); DCHECK(client);
DCHECK(!internal_); DCHECK(!internal_);
internal_ = std::make_unique<Internal>( internal_ =
client, std::move(message_port_request), task_runner); std::make_unique<Internal>(client, std::move(message_port), task_runner);
} }
void CastStreamingSession::Stop() { void CastStreamingSession::Stop() {
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
#ifndef FUCHSIA_CAST_STREAMING_PUBLIC_CAST_STREAMING_SESSION_H_ #ifndef FUCHSIA_CAST_STREAMING_PUBLIC_CAST_STREAMING_SESSION_H_
#define FUCHSIA_CAST_STREAMING_PUBLIC_CAST_STREAMING_SESSION_H_ #define FUCHSIA_CAST_STREAMING_PUBLIC_CAST_STREAMING_SESSION_H_
#include <fuchsia/web/cpp/fidl.h>
#include <memory> #include <memory>
#include "base/callback.h" #include "base/callback.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "components/cast/message_port/message_port.h"
#include "media/base/audio_decoder_config.h" #include "media/base/audio_decoder_config.h"
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/mojo/mojom/media_types.mojom.h" #include "media/mojo/mojom/media_types.mojom.h"
...@@ -93,10 +92,9 @@ class CastStreamingSession { ...@@ -93,10 +92,9 @@ class CastStreamingSession {
// * On failure, OnSessionEnded() will be called. // * On failure, OnSessionEnded() will be called.
// * When a new offer is sent by the Cast Streaming Sender, // * When a new offer is sent by the Cast Streaming Sender,
// OnSessionReinitialization() will be called. // OnSessionReinitialization() will be called.
void Start( void Start(Client* client,
Client* client, std::unique_ptr<cast_api_bindings::MessagePort> message_port,
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request, scoped_refptr<base::SequencedTaskRunner> task_runner);
scoped_refptr<base::SequencedTaskRunner> task_runner);
// Stops the Cast Streaming Session. This can only be called once during the // Stops the Cast Streaming Session. This can only be called once during the
// lifespan of this object and only after a call to Start(). // lifespan of this object and only after a call to Start().
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef FUCHSIA_CAST_STREAMING_STREAM_CONSUMER_H_ #ifndef FUCHSIA_CAST_STREAMING_STREAM_CONSUMER_H_
#define FUCHSIA_CAST_STREAMING_STREAM_CONSUMER_H_ #define FUCHSIA_CAST_STREAMING_STREAM_CONSUMER_H_
#include <fuchsia/media/cpp/fidl.h>
#include "base/callback.h" #include "base/callback.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "media/mojo/mojom/media_types.mojom.h" #include "media/mojo/mojom/media_types.mojom.h"
......
include_rules = [ include_rules = [
"+cc/base/switches.h", "+cc/base/switches.h",
"+components/cast/message_port",
"+components/version_info", "+components/version_info",
"+components/viz/common", "+components/viz/common",
"+components/media_control", "+components/media_control",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "fuchsia/engine/browser/cast_streaming_session_client.h" #include "fuchsia/engine/browser/cast_streaming_session_client.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "components/cast/message_port/message_port_fuchsia.h"
#include "media/base/audio_decoder_config.h" #include "media/base/audio_decoder_config.h"
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/mojo/mojom/media_types.mojom.h" #include "media/mojo/mojom/media_types.mojom.h"
...@@ -33,7 +34,9 @@ void CastStreamingSessionClient::StartMojoConnection( ...@@ -33,7 +34,9 @@ void CastStreamingSessionClient::StartMojoConnection(
void CastStreamingSessionClient::OnReceiverEnabled() { void CastStreamingSessionClient::OnReceiverEnabled() {
DVLOG(1) << __func__; DVLOG(1) << __func__;
DCHECK(message_port_request_); DCHECK(message_port_request_);
cast_streaming_session_.Start(this, std::move(message_port_request_), cast_streaming_session_.Start(this,
cast_api_bindings::MessagePortFuchsia::Create(
std::move(message_port_request_)),
base::SequencedTaskRunnerHandle::Get()); base::SequencedTaskRunnerHandle::Get());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment