Skip to content

Commit

Permalink
[chromecast] Define BindingsManager interface, implement for Fuchsia.
Browse files Browse the repository at this point in the history
Defines the abstract BindingsManager API, which generically defines
the interface used by bindings modules to communicate scripts and
and MessagePorts with the CastRunner.

Implements BindingsManagerFuchsia, which bridges the BindingsManager
and chromium.cast.ApiBindings FIDL interfaces.

Add BindingsManagerFuchsia to Fuchsia's gn_all metatarget, so that
it's discoverable by the Chromium build waterfall.

Bug: 953958
Change-Id: I21fd818096d47e0c5d67dc0fb10a6dcf284800a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1613965
Commit-Queue: Kevin Marshall <kmarshall@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Reviewed-by: Sean Topping <seantopping@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661137}
  • Loading branch information
Kevin Marshall authored and Commit Bot committed May 18, 2019
1 parent 3e2bc92 commit 5e57870
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 1 deletion.
33 changes: 33 additions & 0 deletions chromecast/bindings/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,41 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/fuchsia/rules.gni")

source_set("named_message_port_connector_resources") {
data = [
"named_message_port_connector.js",
]
}

source_set("bindings_manager") {
sources = [
"bindings_manager.cc",
"bindings_manager.h",
]
deps = [
"//base",
]
public_deps = [
"//mojo/public/cpp/bindings",
]
}

source_set("bindings_manager_fuchsia") {
sources = [
"bindings_manager_fuchsia.cc",
"bindings_manager_fuchsia.h",
]

deps = [
"//base",
"//fuchsia:cast_fidl",
"//fuchsia/base",
"//fuchsia/base:message_port",
]

public_deps = [
":bindings_manager",
]
}
4 changes: 4 additions & 0 deletions chromecast/bindings/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include_rules = [
"+fuchsia",
"+mojo/public",
]
41 changes: 41 additions & 0 deletions chromecast/bindings/bindings_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2019 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 "chromecast/bindings/bindings_manager.h"

#include <utility>

namespace chromecast {
namespace bindings {

BindingsManager::BindingsManager() = default;

BindingsManager::~BindingsManager() {
DCHECK(port_handlers_.empty());
}

void BindingsManager::RegisterPortHandler(base::StringPiece port_name,
PortConnectedHandler handler) {
auto result = port_handlers_.try_emplace(port_name, std::move(handler));
DCHECK(result.second);
}

void BindingsManager::UnregisterPortHandler(base::StringPiece port_name) {
size_t deleted = port_handlers_.erase(port_name);
DCHECK_EQ(deleted, 1u);
}

void BindingsManager::OnPortConnected(base::StringPiece port_name,
mojo::ScopedMessagePipeHandle port) {
auto handler = port_handlers_.find(port_name);
if (handler == port_handlers_.end()) {
LOG(ERROR) << "No handler found for port " << port_name << ".";
return;
}

handler->second.Run(std::move(port));
}

} // namespace bindings
} // namespace chromecast
63 changes: 63 additions & 0 deletions chromecast/bindings/bindings_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2019 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.

#ifndef CHROMECAST_BINDINGS_BINDINGS_MANAGER_H_
#define CHROMECAST_BINDINGS_BINDINGS_MANAGER_H_

#include <map>
#include <string>

#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/strings/string_piece.h"
#include "mojo/public/cpp/system/message_pipe.h"

namespace chromecast {
namespace bindings {

// Injects Cast Platform API scripts into pages' scripting context and
// establishes bidirectional communication with them across the JS/native
// boundary.
class BindingsManager {
public:
using PortConnectedHandler =
base::RepeatingCallback<void(mojo::ScopedMessagePipeHandle)>;

BindingsManager();

// All handlers must be Unregistered() before |this| is destroyed.
virtual ~BindingsManager();

// Registers a |handler| which will receive MessagePorts originating from
// the frame's web content. |port_name| is an alphanumeric string that is
// consistent across JS and native code.
void RegisterPortHandler(base::StringPiece port_name,
PortConnectedHandler handler);

// Unregisters a previously registered handler.
// The owner of BindingsManager is responsible for ensuring that all handlers
// are unregistered before |this| is deleted.
void UnregisterPortHandler(base::StringPiece port_name);

// Registers a |binding_script| for injection in the frame.
// Replaces registered bindings with the same |binding_name|.
virtual void AddBinding(base::StringPiece binding_name,
base::StringPiece binding_script) = 0;

protected:
// Called by platform-specific subclasses when the underlying transport has
// delivered a port.
void OnPortConnected(base::StringPiece port_name,
mojo::ScopedMessagePipeHandle port);

private:
base::flat_map<std::string, PortConnectedHandler> port_handlers_;

DISALLOW_COPY_AND_ASSIGN(BindingsManager);
};

} // namespace bindings
} // namespace chromecast

#endif // CHROMECAST_BINDINGS_BINDINGS_MANAGER_H_
50 changes: 50 additions & 0 deletions chromecast/bindings/bindings_manager_fuchsia.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2019 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 "chromecast/bindings/bindings_manager_fuchsia.h"

#include <utility>
#include <vector>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "fuchsia/base/message_port.h"

namespace chromecast {
namespace bindings {

BindingsManagerFuchsia::BindingsManagerFuchsia() = default;

BindingsManagerFuchsia::~BindingsManagerFuchsia() = default;

void BindingsManagerFuchsia::AddBinding(base::StringPiece binding_name,
base::StringPiece binding_script) {
bindings_[binding_name.as_string()] =
cr_fuchsia::MemBufferFromString(binding_script);
}

void BindingsManagerFuchsia::GetAll(GetAllCallback callback) {
// Build a list of binding scripts and send it to the client.
std::vector<chromium::cast::ApiBinding> bindings_vector;
for (auto& bindings_name_and_buffer : bindings_) {
chromium::cast::ApiBinding binding_cloned;
zx_status_t status;
status = bindings_name_and_buffer.second.Clone(
binding_cloned.mutable_before_load_script());
ZX_CHECK(status == ZX_OK, status) << "vmo::clone";
bindings_vector.emplace_back(std::move(binding_cloned));
}
callback(std::move(bindings_vector));
}

void BindingsManagerFuchsia::Connect(
std::string port_name,
fidl::InterfaceHandle<::fuchsia::web::MessagePort> message_port) {
OnPortConnected(port_name,
cr_fuchsia::MessagePortFromFidl(std::move(message_port)));
}

} // namespace bindings
} // namespace chromecast
47 changes: 47 additions & 0 deletions chromecast/bindings/bindings_manager_fuchsia.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2019 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.

#ifndef CHROMECAST_BINDINGS_BINDINGS_MANAGER_FUCHSIA_H_
#define CHROMECAST_BINDINGS_BINDINGS_MANAGER_FUCHSIA_H_

#include <map>
#include <string>

#include "base/callback.h"
#include "chromecast/bindings/bindings_manager.h"
#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"

namespace chromecast {
namespace bindings {

// Implements the BindingsManager as a ApiBindings FIDL service.
class BindingsManagerFuchsia : public chromium::cast::ApiBindings,
public BindingsManager {
public:
BindingsManagerFuchsia();
~BindingsManagerFuchsia() override;

// BindingsManager implementation:
void AddBinding(base::StringPiece binding_name,
base::StringPiece binding_script) override;

protected:
// chromium::cast::ApiBindings implementation:
void GetAll(GetAllCallback callback) override;
void Connect(
std::string port_name,
fidl::InterfaceHandle<::fuchsia::web::MessagePort> message_port) override;

private:
// Stores all bindings, keyed on the string-based IDs provided by the
// ApiBindings interface.
std::map<std::string, fuchsia::mem::Buffer> bindings_;

DISALLOW_COPY_AND_ASSIGN(BindingsManagerFuchsia);
};

} // namespace bindings
} // namespace chromecast

#endif // CHROMECAST_BINDINGS_BINDINGS_MANAGER_FUCHSIA_H_
1 change: 1 addition & 0 deletions fuchsia/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ group("gn_all") {
"runners:cast_runner_browsertests",
"runners:cast_runner_integration_tests",
"runners:web_runner",
"//chromecast/bindings:bindings_manager_fuchsia",
]
}
2 changes: 1 addition & 1 deletion fuchsia/fidl/cast/api_bindings.fidl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protocol ApiBindings {

/// Should be invoked when a connecting a named MessagePort to a native
/// bindings backend.
Connect(string api_name, fuchsia.web.MessagePort message_port);
Connect(string port_name, fuchsia.web.MessagePort message_port);
};

table ApiBinding {
Expand Down

0 comments on commit 5e57870

Please sign in to comment.