Commit e15433f3 authored by Wez's avatar Wez Committed by Commit Bot

[fuchsia] Simplify implementation of the CastRunner.

The implementation of the fuchsia.sys.Runner for Cast apps is refactored
to be easier to maintain, in the following ways:

1. Instead of deriving from WebContentRunner and overriding certain
   behaviours, the CastRunner now instantiates WebContentRunner instances
   internally, to use to manage CastComponents.

2. CastRunner now implements fuchsia.sys.Runner itself, and manages the
   PendingCastComponents, prior to creating & handing off CastComponents
   to be managed by the WebContentRunner(s).

3. The CreateContextParams for the main and isolated contexts are
   constructed using a common base, rather than copying & filtering the
   main context parameters, to create parameters for isolated contexts.

Bug: 1071544
Change-Id: Ic66ca0a9805e9b00d213c62845e5101ff9dea76e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2153055
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarDavid Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#761177}
parent 07596fa6
...@@ -46,10 +46,13 @@ bool CastComponent::Params::AreComplete() const { ...@@ -46,10 +46,13 @@ bool CastComponent::Params::AreComplete() const {
return true; return true;
} }
CastComponent::CastComponent(CastRunner* runner, CastComponent::Params params) CastComponent::CastComponent(WebContentRunner* runner,
CastComponent::Params params,
bool is_headless)
: WebComponent(runner, : WebComponent(runner,
std::move(params.startup_context), std::move(params.startup_context),
std::move(params.controller_request)), std::move(params.controller_request)),
is_headless_(is_headless),
agent_manager_(std::move(params.agent_manager)), agent_manager_(std::move(params.agent_manager)),
application_config_(std::move(params.application_config)), application_config_(std::move(params.application_config)),
url_rewrite_rules_provider_(std::move(params.url_rewrite_rules_provider)), url_rewrite_rules_provider_(std::move(params.url_rewrite_rules_provider)),
...@@ -64,6 +67,10 @@ CastComponent::CastComponent(CastRunner* runner, CastComponent::Params params) ...@@ -64,6 +67,10 @@ CastComponent::CastComponent(CastRunner* runner, CastComponent::Params params)
CastComponent::~CastComponent() = default; CastComponent::~CastComponent() = default;
void CastComponent::SetOnDestroyedCallback(base::OnceClosure on_destroyed) {
on_destroyed_ = std::move(on_destroyed);
}
void CastComponent::StartComponent() { void CastComponent::StartComponent() {
if (application_config_.has_enable_remote_debugging() && if (application_config_.has_enable_remote_debugging() &&
application_config_.enable_remote_debugging()) { application_config_.enable_remote_debugging()) {
...@@ -116,14 +123,12 @@ void CastComponent::StartComponent() { ...@@ -116,14 +123,12 @@ void CastComponent::StartComponent() {
} }
} }
CastRunner* CastComponent::runner() const {
return static_cast<CastRunner*>(WebComponent::runner());
}
void CastComponent::DestroyComponent(int termination_exit_code, void CastComponent::DestroyComponent(int termination_exit_code,
fuchsia::sys::TerminationReason reason) { fuchsia::sys::TerminationReason reason) {
DCHECK(!constructor_active_); DCHECK(!constructor_active_);
std::move(on_destroyed_).Run();
WebComponent::DestroyComponent(termination_exit_code, reason); WebComponent::DestroyComponent(termination_exit_code, reason);
} }
...@@ -147,7 +152,7 @@ void CastComponent::CreateView( ...@@ -147,7 +152,7 @@ void CastComponent::CreateView(
zx::eventpair view_token, zx::eventpair view_token,
fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services, fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) { fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) {
if (runner()->is_headless()) { if (is_headless_) {
// For headless CastComponents, |view_token| does not actually connect to a // For headless CastComponents, |view_token| does not actually connect to a
// Scenic View. It is merely used as a conduit for propagating termination // Scenic View. It is merely used as a conduit for propagating termination
// signals. // signals.
...@@ -167,7 +172,7 @@ void CastComponent::CreateView( ...@@ -167,7 +172,7 @@ void CastComponent::CreateView(
void CastComponent::OnZxHandleSignalled(zx_handle_t handle, void CastComponent::OnZxHandleSignalled(zx_handle_t handle,
zx_signals_t signals) { zx_signals_t signals) {
DCHECK_EQ(signals, ZX_SOCKET_PEER_CLOSED); DCHECK_EQ(signals, ZX_SOCKET_PEER_CLOSED);
DCHECK(runner()->is_headless()); DCHECK(is_headless_);
frame()->DisableHeadlessRendering(); frame()->DisableHeadlessRendering();
} }
...@@ -23,8 +23,6 @@ namespace cr_fuchsia { ...@@ -23,8 +23,6 @@ namespace cr_fuchsia {
class AgentManager; class AgentManager;
} }
class CastRunner;
FORWARD_DECLARE_TEST(HeadlessCastRunnerIntegrationTest, Headless); FORWARD_DECLARE_TEST(HeadlessCastRunnerIntegrationTest, Headless);
// A specialization of WebComponent which adds Cast-specific services. // A specialization of WebComponent which adds Cast-specific services.
...@@ -62,11 +60,15 @@ class CastComponent : public WebComponent, ...@@ -62,11 +60,15 @@ class CastComponent : public WebComponent,
base::Optional<uint64_t> media_session_id; base::Optional<uint64_t> media_session_id;
}; };
CastComponent(CastRunner* runner, Params params); CastComponent(WebContentRunner* runner, Params params, bool is_headless);
~CastComponent() final; ~CastComponent() final;
void SetOnDestroyedCallback(base::OnceClosure on_destroyed);
// WebComponent overrides. // WebComponent overrides.
void StartComponent() final; void StartComponent() final;
void DestroyComponent(int termination_exit_code,
fuchsia::sys::TerminationReason reason) final;
const chromium::cast::ApplicationConfig& application_config() { const chromium::cast::ApplicationConfig& application_config() {
return application_config_; return application_config_;
...@@ -74,16 +76,10 @@ class CastComponent : public WebComponent, ...@@ -74,16 +76,10 @@ class CastComponent : public WebComponent,
cr_fuchsia::AgentManager* agent_manager() { return agent_manager_.get(); } cr_fuchsia::AgentManager* agent_manager() { return agent_manager_.get(); }
CastRunner* runner() const;
private: private:
void OnRewriteRulesReceived( void OnRewriteRulesReceived(
std::vector<fuchsia::web::UrlRequestRewriteRule> url_rewrite_rules); std::vector<fuchsia::web::UrlRequestRewriteRule> url_rewrite_rules);
// WebComponent overrides.
void DestroyComponent(int termination_exit_code,
fuchsia::sys::TerminationReason reason) final;
// fuchsia::web::NavigationEventListener implementation. // fuchsia::web::NavigationEventListener implementation.
// Triggers the injection of API channels into the page content. // Triggers the injection of API channels into the page content.
void OnNavigationStateChanged( void OnNavigationStateChanged(
...@@ -101,6 +97,9 @@ class CastComponent : public WebComponent, ...@@ -101,6 +97,9 @@ class CastComponent : public WebComponent,
// Called when the headless "view" token is disconnected. // Called when the headless "view" token is disconnected.
void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) final; void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) final;
const bool is_headless_;
base::OnceClosure on_destroyed_;
std::unique_ptr<cr_fuchsia::AgentManager> agent_manager_; std::unique_ptr<cr_fuchsia::AgentManager> agent_manager_;
chromium::cast::ApplicationConfig application_config_; chromium::cast::ApplicationConfig application_config_;
chromium::cast::UrlRequestRewriteRulesProviderPtr url_rewrite_rules_provider_; chromium::cast::UrlRequestRewriteRulesProviderPtr url_rewrite_rules_provider_;
......
This diff is collapsed.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ #ifndef FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_
#define FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ #define FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_
#include <chromium/cast/cpp/fidl.h>
#include <fuchsia/legacymetrics/cpp/fidl.h> #include <fuchsia/legacymetrics/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h> #include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/web/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h>
...@@ -13,14 +14,12 @@ ...@@ -13,14 +14,12 @@
#include <vector> #include <vector>
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h" #include "base/containers/unique_ptr_adapters.h"
#include "base/fuchsia/startup_context.h" #include "base/fuchsia/startup_context.h"
#include "base/macros.h"
#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
#include "fuchsia/runners/cast/cast_component.h" #include "fuchsia/runners/cast/cast_component.h"
#include "fuchsia/runners/cast/pending_cast_component.h" #include "fuchsia/runners/cast/pending_cast_component.h"
#include "fuchsia/runners/common/web_content_runner.h"
namespace base { namespace base {
namespace fuchsia { namespace fuchsia {
...@@ -28,76 +27,80 @@ class FilteredServiceDirectory; ...@@ -28,76 +27,80 @@ class FilteredServiceDirectory;
} // namespace fuchsia } // namespace fuchsia
} // namespace base } // namespace base
class WebContentRunner;
// sys::Runner which instantiates Cast activities specified via cast/casts URIs. // sys::Runner which instantiates Cast activities specified via cast/casts URIs.
class CastRunner : public WebContentRunner, class CastRunner : public fuchsia::sys::Runner,
public PendingCastComponent::Delegate { public PendingCastComponent::Delegate {
public: public:
using OnDestructionCallback = base::OnceCallback<void(CastRunner*)>;
static constexpr uint16_t kRemoteDebuggingPort = 9222; static constexpr uint16_t kRemoteDebuggingPort = 9222;
// Creates a Runner for Cast components. // Creates the Runner for Cast components.
// |get_context_params_callback|: Returns the context parameters to use. // |is_headless|: True if this instance should create Contexts with the
// |is_headless|: True if |get_context_params_callback| sets the HEADLESS // HEADLESS feature set.
// feature flag. explicit CastRunner(bool is_headless);
CastRunner(GetContextParamsCallback get_context_params_callback,
bool is_headless);
~CastRunner() final; ~CastRunner() final;
CastRunner(const CastRunner&) = delete; CastRunner(const CastRunner&) = delete;
CastRunner& operator=(const CastRunner&) = delete; CastRunner& operator=(const CastRunner&) = delete;
// WebContentRunner implementation.
void DestroyComponent(WebComponent* component) final;
// fuchsia::sys::Runner implementation. // fuchsia::sys::Runner implementation.
void StartComponent(fuchsia::sys::Package package, void StartComponent(fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info, fuchsia::sys::StartupInfo startup_info,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> fidl::InterfaceRequest<fuchsia::sys::ComponentController>
controller_request) final; controller_request) final;
// Returns true if this Runner is configured not to use Scenic. void SetOnMainContextLostCallbackForTest(base::OnceClosure on_context_lost);
bool is_headless() const { return is_headless_; }
private: // Disables use of the VULKAN feature when creating Contexts. Must be set
// Creates and returns the service directory that is passed to the main web // before calling StartComponent().
// context. void set_disable_vulkan_for_test() { disable_vulkan_for_test_ = true; }
std::unique_ptr<base::fuchsia::FilteredServiceDirectory>
CreateServiceDirectory();
private:
// PendingCastComponent::Delegate implementation. // PendingCastComponent::Delegate implementation.
void LaunchPendingComponent(PendingCastComponent* pending_component, void LaunchPendingComponent(PendingCastComponent* pending_component,
CastComponent::Params params) final; CastComponent::Params params) final;
void CancelPendingComponent(PendingCastComponent* pending_component) final; void CancelPendingComponent(PendingCastComponent* pending_component) final;
// Creates a component in this Runner, using the supplied |params|. // Handles component destruction.
void CreateAndRegisterCastComponent(CastComponent::Params component_params); void OnComponentDestroyed(CastComponent* component);
// Called when the isolated component in |runner| is ready to be destroyed. // Handlers used to provide parameters for main & isolated Contexts.
void OnIsolatedRunnerEmpty(CastRunner* runner); fuchsia::web::CreateContextParams GetCommonContextParams();
fuchsia::web::CreateContextParams GetMainContextParams();
fuchsia::web::CreateContextParams GetIsolatedContextParams(
std::vector<fuchsia::web::ContentDirectoryProvider> content_directories);
// Creates a CastRunner configured to serve data from content directories in // Creates a CastRunner configured to serve data from content directories in
// |params|. // |component_params|.
CastRunner* CreateChildRunnerForIsolatedComponent( WebContentRunner* CreateIsolatedContextForParams(
CastComponent::Params* component_params); CastComponent::Params* component_params);
// Handler for fuchsia.media.Audio requests in |service_directory_|. // Called when an isolated component terminates, to allow the Context hosting
void ConnectAudioProtocol( // it to be torn down.
fidl::InterfaceRequest<fuchsia::media::Audio> request); void OnIsolatedContextEmpty(WebContentRunner* context);
// Handler for fuchsia.legacymetrics.MetricsRecorder requests in // Connection handlers for redirected services.
// |service_directory_|. void OnAudioServiceRequest(
void ConnectMetricsRecorderProtocol( fidl::InterfaceRequest<fuchsia::media::Audio> request);
void OnMetricsRecorderServiceRequest(
fidl::InterfaceRequest<fuchsia::legacymetrics::MetricsRecorder> request); fidl::InterfaceRequest<fuchsia::legacymetrics::MetricsRecorder> request);
// Returns the parameters with which the main context should be created.
fuchsia::web::CreateContextParams GetMainContextParams();
const WebContentRunner::GetContextParamsCallback get_context_params_callback_;
// True if this Runner uses Context(s) with the HEADLESS feature set. // True if this Runner uses Context(s) with the HEADLESS feature set.
const bool is_headless_; const bool is_headless_;
// Holds the main fuchsia.web.Context used to host CastComponents.
// Note that although |main_context_| is actually a WebContentRunner, that is
// only being used to maintain the Context for the hosted components.
const std::unique_ptr<base::fuchsia::FilteredServiceDirectory> main_services_;
const std::unique_ptr<WebContentRunner> main_context_;
// Holds fuchsia.web.Contexts used to host isolated components.
const std::unique_ptr<base::fuchsia::FilteredServiceDirectory>
isolated_services_;
base::flat_set<std::unique_ptr<WebContentRunner>, base::UniquePtrComparator>
isolated_contexts_;
// Temporarily holds a PendingCastComponent instance, responsible for fetching // Temporarily holds a PendingCastComponent instance, responsible for fetching
// the parameters required to launch the component, for each call to // the parameters required to launch the component, for each call to
// StartComponent(). // StartComponent().
...@@ -105,21 +108,11 @@ class CastRunner : public WebContentRunner, ...@@ -105,21 +108,11 @@ class CastRunner : public WebContentRunner,
base::UniquePtrComparator> base::UniquePtrComparator>
pending_components_; pending_components_;
// Invoked upon destruction of "isolated" runners, used to signal termination
// to parents.
OnDestructionCallback on_component_destroyed_callback_;
// Manages isolated CastRunners owned by |this| instance.
base::flat_set<std::unique_ptr<CastRunner>, base::UniquePtrComparator>
isolated_runners_;
// ServiceDirectory passed to the main Context, to allow Audio capturer
// service requests to be routed to the relevant Agent.
const std::unique_ptr<base::fuchsia::FilteredServiceDirectory>
service_directory_;
// Last component that was created with permission to access MICROPHONE. // Last component that was created with permission to access MICROPHONE.
CastComponent* audio_capturer_component_ = nullptr; CastComponent* audio_capturer_component_ = nullptr;
// True if Contexts should be created without VULKAN set.
bool disable_vulkan_for_test_ = false;
}; };
#endif // FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ #endif // FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_
...@@ -225,32 +225,10 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -225,32 +225,10 @@ class CastRunnerIntegrationTest : public testing::Test {
EnsureFuchsiaDirSchemeInitialized(); EnsureFuchsiaDirSchemeInitialized();
// Create the CastRunner, published into |outgoing_directory_|. // Create the CastRunner, published into |outgoing_directory_|.
fuchsia::web::ContextFeatureFlags feature_flags = cast_runner_ = std::make_unique<CastRunner>(enable_headless);
fuchsia::web::ContextFeatureFlags::NETWORK | if (!enable_vulkan)
fuchsia::web::ContextFeatureFlags::LEGACYMETRICS; cast_runner_->set_disable_vulkan_for_test();
if (enable_headless) { cast_runner_binding_.emplace(&outgoing_directory_, cast_runner_.get());
feature_flags |= fuchsia::web::ContextFeatureFlags::HEADLESS;
}
if (enable_vulkan) {
feature_flags |= fuchsia::web::ContextFeatureFlags::VULKAN;
}
WebContentRunner::GetContextParamsCallback get_context_params =
base::BindLambdaForTesting([feature_flags]() {
fuchsia::web::CreateContextParams create_context_params;
create_context_params.set_features(feature_flags);
create_context_params.set_service_directory(
base::fuchsia::OpenDirectory(
base::FilePath(base::fuchsia::kServiceDirectoryPath)));
CHECK(create_context_params.service_directory());
create_context_params.set_remote_debugging_port(
CastRunner::kRemoteDebuggingPort);
return create_context_params;
});
cast_runner_ = std::make_unique<CastRunner>(std::move(get_context_params),
enable_headless);
cast_runner_->PublishRunnerService(&outgoing_directory_);
StartAndPublishWebEngine(); StartAndPublishWebEngine();
...@@ -500,6 +478,8 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -500,6 +478,8 @@ class CastRunnerIntegrationTest : public testing::Test {
sys::OutgoingDirectory outgoing_directory_; sys::OutgoingDirectory outgoing_directory_;
std::unique_ptr<CastRunner> cast_runner_; std::unique_ptr<CastRunner> cast_runner_;
base::Optional<base::fuchsia::ScopedServiceBinding<fuchsia::sys::Runner>>
cast_runner_binding_;
fuchsia::sys::RunnerPtr cast_runner_ptr_; fuchsia::sys::RunnerPtr cast_runner_ptr_;
base::TestComponentContextForProcess test_component_context_{ base::TestComponentContextForProcess test_component_context_{
base::TestComponentContextForProcess::InitialState::kCloneAll}; base::TestComponentContextForProcess::InitialState::kCloneAll};
...@@ -535,7 +515,8 @@ TEST_F(CastRunnerIntegrationTest, CanRecreateContext) { ...@@ -535,7 +515,8 @@ TEST_F(CastRunnerIntegrationTest, CanRecreateContext) {
// Setup a loop to wait for Context destruction after WebEngine is killed // Setup a loop to wait for Context destruction after WebEngine is killed
// below. // below.
base::RunLoop context_lost_loop; base::RunLoop context_lost_loop;
cast_runner_->SetOnContextLostCallback(context_lost_loop.QuitClosure()); cast_runner_->SetOnMainContextLostCallbackForTest(
context_lost_loop.QuitClosure());
web_engine_controller_->Kill(); web_engine_controller_->Kill();
......
...@@ -6,18 +6,15 @@ ...@@ -6,18 +6,15 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/fuchsia/default_context.h" #include "base/fuchsia/default_context.h"
#include "base/fuchsia/file_utils.h" #include "base/fuchsia/scoped_service_binding.h"
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/no_destructor.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h" #include "base/task/single_thread_task_executor.h"
#include "base/values.h" #include "base/values.h"
#include "build/buildflag.h"
#include "fuchsia/base/config_reader.h" #include "fuchsia/base/config_reader.h"
#include "fuchsia/base/fuchsia_dir_scheme.h" #include "fuchsia/base/fuchsia_dir_scheme.h"
#include "fuchsia/base/init_logging.h" #include "fuchsia/base/init_logging.h"
#include "fuchsia/runners/buildflags.h"
#include "fuchsia/runners/cast/cast_runner.h" #include "fuchsia/runners/cast/cast_runner.h"
namespace { namespace {
...@@ -34,43 +31,6 @@ bool IsHeadless() { ...@@ -34,43 +31,6 @@ bool IsHeadless() {
return false; return false;
} }
fuchsia::web::CreateContextParams CreateMainContextParams() {
fuchsia::web::ContextFeatureFlags features =
fuchsia::web::ContextFeatureFlags::NETWORK |
fuchsia::web::ContextFeatureFlags::AUDIO |
fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM |
fuchsia::web::ContextFeatureFlags::LEGACYMETRICS;
if (IsHeadless()) {
LOG(WARNING) << "Running in headless mode.";
features |= fuchsia::web::ContextFeatureFlags::HEADLESS;
} else {
features |= fuchsia::web::ContextFeatureFlags::VULKAN |
fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER |
fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER_ONLY;
}
fuchsia::web::CreateContextParams create_context_params;
create_context_params.set_features(features);
const char kCastPlayreadyKeySystem[] = "com.chromecast.playready";
create_context_params.set_playready_key_system(kCastPlayreadyKeySystem);
// TODO(b/141956135): Use CrKey version provided by the Agent.
create_context_params.set_user_agent_product("CrKey");
create_context_params.set_user_agent_version("1.43.000000");
create_context_params.set_remote_debugging_port(
CastRunner::kRemoteDebuggingPort);
// TODO(crbug.com/1023514): Remove this switch when it is no longer
// necessary.
create_context_params.set_unsafely_treat_insecure_origins_as_secure(
{"allow-running-insecure-content"});
return create_context_params;
}
} // namespace } // namespace
int main(int argc, char** argv) { int main(int argc, char** argv) {
...@@ -84,12 +44,10 @@ int main(int argc, char** argv) { ...@@ -84,12 +44,10 @@ int main(int argc, char** argv) {
cr_fuchsia::RegisterFuchsiaDirScheme(); cr_fuchsia::RegisterFuchsiaDirScheme();
WebContentRunner::GetContextParamsCallback get_context_params_callback = CastRunner runner(IsHeadless());
base::BindRepeating(&CreateMainContextParams); base::fuchsia::ScopedServiceBinding<fuchsia::sys::Runner> binding(
base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get(),
CastRunner runner(std::move(get_context_params_callback), IsHeadless()); &runner);
runner.PublishRunnerService(
base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get());
base::fuchsia::ComponentContextForCurrentProcess() base::fuchsia::ComponentContextForCurrentProcess()
->outgoing() ->outgoing()
......
...@@ -65,8 +65,7 @@ void WebComponent::StartComponent() { ...@@ -65,8 +65,7 @@ void WebComponent::StartComponent() {
// Create the underlying Frame and get its NavigationController. // Create the underlying Frame and get its NavigationController.
fuchsia::web::CreateFrameParams create_params; fuchsia::web::CreateFrameParams create_params;
create_params.set_enable_remote_debugging(enable_remote_debugging_); create_params.set_enable_remote_debugging(enable_remote_debugging_);
runner_->GetContext()->CreateFrameWithParams(std::move(create_params), frame_ = runner_->CreateFrame(std::move(create_params));
frame_.NewRequest());
// If the Frame unexpectedly disconnect us then tear-down this Component. // If the Frame unexpectedly disconnect us then tear-down this Component.
frame_.set_error_handler([this](zx_status_t status) { frame_.set_error_handler([this](zx_status_t status) {
......
...@@ -41,26 +41,32 @@ WebContentRunner::WebContentRunner( ...@@ -41,26 +41,32 @@ WebContentRunner::WebContentRunner(
GetContextParamsCallback get_context_params_callback) GetContextParamsCallback get_context_params_callback)
: get_context_params_callback_(std::move(get_context_params_callback)) {} : get_context_params_callback_(std::move(get_context_params_callback)) {}
WebContentRunner::~WebContentRunner() = default; WebContentRunner::WebContentRunner(
fuchsia::web::CreateContextParams context_params)
void WebContentRunner::PublishRunnerService( : context_(CreateWebContext(std::move(context_params))) {
sys::OutgoingDirectory* outgoing_directory) { context_.set_error_handler([](zx_status_t status) {
service_binding_.emplace(outgoing_directory, this); ZX_LOG(ERROR, status) << "Connection to one-shot Context lost.";
});
} }
fuchsia::web::Context* WebContentRunner::GetContext() { WebContentRunner::~WebContentRunner() = default;
fuchsia::web::FramePtr WebContentRunner::CreateFrame(
fuchsia::web::CreateFrameParams params) {
if (!context_) { if (!context_) {
DCHECK(get_context_params_callback_);
context_ = CreateWebContext(get_context_params_callback_.Run()); context_ = CreateWebContext(get_context_params_callback_.Run());
context_.set_error_handler([this](zx_status_t status) { context_.set_error_handler([this](zx_status_t status) {
// If the browser instance died, then exit everything and do not attempt
// to recover. appmgr will relaunch the runner when it is needed again.
ZX_LOG(ERROR, status) << "Connection to Context lost."; ZX_LOG(ERROR, status) << "Connection to Context lost.";
if (on_context_lost_callback_) { if (on_context_lost_callback_) {
std::move(on_context_lost_callback_).Run(); std::move(on_context_lost_callback_).Run();
} }
}); });
} }
return context_.get();
fuchsia::web::FramePtr frame;
context_->CreateFrameWithParams(std::move(params), frame.NewRequest());
return frame;
} }
void WebContentRunner::StartComponent( void WebContentRunner::StartComponent(
...@@ -95,6 +101,8 @@ WebComponent* WebContentRunner::GetAnyComponent() { ...@@ -95,6 +101,8 @@ WebComponent* WebContentRunner::GetAnyComponent() {
void WebContentRunner::DestroyComponent(WebComponent* component) { void WebContentRunner::DestroyComponent(WebComponent* component) {
components_.erase(components_.find(component)); components_.erase(components_.find(component));
if (components_.empty() && on_empty_callback_)
std::move(on_empty_callback_).Run();
} }
void WebContentRunner::RegisterComponent( void WebContentRunner::RegisterComponent(
...@@ -102,6 +110,11 @@ void WebContentRunner::RegisterComponent( ...@@ -102,6 +110,11 @@ void WebContentRunner::RegisterComponent(
components_.insert(std::move(component)); components_.insert(std::move(component));
} }
void WebContentRunner::SetOnContextLostCallback(base::OnceClosure callback) { void WebContentRunner::SetOnEmptyCallback(base::OnceClosure on_empty) {
on_empty_callback_ = std::move(on_empty);
}
void WebContentRunner::SetOnContextLostCallbackForTest(
base::OnceClosure callback) {
on_context_lost_callback_ = std::move(callback); on_context_lost_callback_ = std::move(callback);
} }
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/unique_ptr_adapters.h" #include "base/containers/unique_ptr_adapters.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
...@@ -25,24 +24,26 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -25,24 +24,26 @@ class WebContentRunner : public fuchsia::sys::Runner {
using GetContextParamsCallback = using GetContextParamsCallback =
base::RepeatingCallback<fuchsia::web::CreateContextParams()>; base::RepeatingCallback<fuchsia::web::CreateContextParams()>;
// Creates a Runner for web-based components, and publishes it to the // Creates a Runner which will (re-)create the Context, if not already
// specified OutgoingDirectory. // running, when StartComponent() is called,
// |get_context_params_callback|: Returns parameters for the Runner's // |get_context_params_callback|: Returns parameters for the Runner's
// web.Context. // fuchsia.web.Context.
explicit WebContentRunner( explicit WebContentRunner(
GetContextParamsCallback get_context_params_callback); GetContextParamsCallback get_context_params_callback);
~WebContentRunner() override; // Creates a Runner using a Context configured with |context_params|.
// The Runner becomes non-functional if the Context terminates.
explicit WebContentRunner(fuchsia::web::CreateContextParams context_params);
// Publishes the fuchsia.sys.Runner service to |outgoing_directory|. ~WebContentRunner() override;
void PublishRunnerService(sys::OutgoingDirectory* outgoing_directory);
// Gets a pointer to this runner's Context, creating one if needed. // Creates a Frame in this Runner's Context. If no Context exists then
fuchsia::web::Context* GetContext(); // |get_context_params_callback_| will be used to create one, if set.
fuchsia::web::FramePtr CreateFrame(fuchsia::web::CreateFrameParams params);
// Used by WebComponent instances to signal that the ComponentController // Used by WebComponent instances to signal that the ComponentController
// channel was dropped, and therefore the component should be destroyed. // channel was dropped, and therefore the component should be destroyed.
virtual void DestroyComponent(WebComponent* component); void DestroyComponent(WebComponent* component);
// fuchsia::sys::Runner implementation. // fuchsia::sys::Runner implementation.
void StartComponent(fuchsia::sys::Package package, void StartComponent(fuchsia::sys::Package package,
...@@ -53,10 +54,14 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -53,10 +54,14 @@ class WebContentRunner : public fuchsia::sys::Runner {
// Registers a WebComponent, or specialization, with this Runner. // Registers a WebComponent, or specialization, with this Runner.
void RegisterComponent(std::unique_ptr<WebComponent> component); void RegisterComponent(std::unique_ptr<WebComponent> component);
// Sets a callback that's called when the context is lost. // Sets a callback to invoke when |components_| next becomes empty.
void SetOnContextLostCallback(base::OnceClosure callback); void SetOnEmptyCallback(base::OnceClosure on_empty);
// Sets a callback that's called when |context_| disconnects.
void SetOnContextLostCallbackForTest(base::OnceClosure on_context_lost);
protected: // TODO(https://crbug.com/1065707): Remove this once capability routing for
// the fuchsia.legacymetrics.Provider service is properly set up.
// Returns a pointer to any currently running component, or nullptr if no // Returns a pointer to any currently running component, or nullptr if no
// components are currently running. // components are currently running.
WebComponent* GetAnyComponent(); WebComponent* GetAnyComponent();
...@@ -72,10 +77,7 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -72,10 +77,7 @@ class WebContentRunner : public fuchsia::sys::Runner {
std::set<std::unique_ptr<WebComponent>, base::UniquePtrComparator> std::set<std::unique_ptr<WebComponent>, base::UniquePtrComparator>
components_; components_;
// Publishes this Runner into the service directory specified at construction. base::OnceClosure on_empty_callback_;
// This is not set for child runner instances.
base::Optional<base::fuchsia::ScopedServiceBinding<fuchsia::sys::Runner>>
service_binding_;
base::OnceClosure on_context_lost_callback_; base::OnceClosure on_context_lost_callback_;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/fuchsia/default_context.h" #include "base/fuchsia/default_context.h"
#include "base/fuchsia/file_utils.h" #include "base/fuchsia/file_utils.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h" #include "base/task/single_thread_task_executor.h"
...@@ -58,8 +59,9 @@ int main(int argc, char** argv) { ...@@ -58,8 +59,9 @@ int main(int argc, char** argv) {
base::BindRepeating(&GetContextParams); base::BindRepeating(&GetContextParams);
WebContentRunner runner(std::move(get_context_params_callback)); WebContentRunner runner(std::move(get_context_params_callback));
runner.PublishRunnerService( base::fuchsia::ScopedServiceBinding<fuchsia::sys::Runner> binding(
base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get()); base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get(),
&runner);
base::fuchsia::ComponentContextForCurrentProcess() base::fuchsia::ComponentContextForCurrentProcess()
->outgoing() ->outgoing()
......
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