blob: 1ab17c5d6a27024d95247557957ff1d91be6dcc6 [file] [log] [blame]
// 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 "fuchsia/runners/cast/cast_component.h"
#include <lib/fidl/cpp/binding.h>
#include <algorithm>
#include <utility>
#include "base/auto_reset.h"
#include "base/files/file_util.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/path_service.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
#include "fuchsia/runners/cast/cast_platform_bindings_ids.h"
#include "fuchsia/runners/cast/cast_runner.h"
#include "fuchsia/runners/common/web_component.h"
namespace {
constexpr int kBindingsFailureExitCode = 129;
constexpr char kStubBindingsPath[] =
FILE_PATH_LITERAL("fuchsia/runners/cast/not_implemented_api_bindings.js");
} // namespace
CastComponent::CastComponent(
CastRunner* runner,
std::unique_ptr<base::fuchsia::StartupContext> context,
fidl::InterfaceRequest<fuchsia::sys::ComponentController>
controller_request,
std::unique_ptr<cr_fuchsia::AgentManager> agent_manager)
: WebComponent(runner, std::move(context), std::move(controller_request)),
agent_manager_(std::move(agent_manager)),
navigation_listener_binding_(this) {
base::AutoReset<bool> constructor_active_reset(&constructor_active_, true);
InitializeCastPlatformBindings();
frame()->SetNavigationEventListener(
navigation_listener_binding_.NewBinding());
}
CastComponent::~CastComponent() = default;
void CastComponent::DestroyComponent(int termination_exit_code,
fuchsia::sys::TerminationReason reason) {
DCHECK(!constructor_active_);
WebComponent::DestroyComponent(termination_exit_code, reason);
}
void CastComponent::OnNavigationStateChanged(
fuchsia::web::NavigationState change,
OnNavigationStateChangedCallback callback) {
if (change.has_url())
connector_.NotifyPageLoad(frame());
callback();
}
void CastComponent::InitializeCastPlatformBindings() {
base::FilePath stub_path;
CHECK(base::PathService::Get(base::DIR_ASSETS, &stub_path));
stub_path = stub_path.AppendASCII(kStubBindingsPath);
DCHECK(base::PathExists(stub_path));
fuchsia::mem::Buffer stub_buf = cr_fuchsia::MemBufferFromFile(
base::File(stub_path, base::File::FLAG_OPEN | base::File::FLAG_READ));
CHECK(stub_buf.vmo);
frame()->AddBeforeLoadJavaScript(
static_cast<uint64_t>(CastPlatformBindingsId::NOT_IMPLEMENTED_API), {"*"},
std::move(stub_buf),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
CHECK(result.is_response()) << "Couldn't inject stub bindings.";
});
cast_channel_ = std::make_unique<CastChannelBindings>(
frame(), &connector_,
agent_manager_->ConnectToAgentService<chromium::cast::CastChannel>(
CastRunner::kAgentComponentUrl),
base::BindOnce(&CastComponent::DestroyComponent, base::Unretained(this),
kBindingsFailureExitCode,
fuchsia::sys::TerminationReason::INTERNAL_ERROR));
queryable_data_ = std::make_unique<QueryableDataBindings>(
frame(),
agent_manager_->ConnectToAgentService<chromium::cast::QueryableData>(
CastRunner::kAgentComponentUrl));
}