Commit 0aaffc1b authored by Wez's avatar Wez Committed by Commit Bot

[fuchsia] Fix WebContentRunner to handle Context failures.

WebContentRunner used to exit() if its Context terminated unexpectedly.
This was removed when support was added for a single Runner service to
run WebComponents in their own isolated Contexts. Launch of the Context
requires move()ing the contents of the CreateContextParams, resulting in
some of its fields (in particular the service-directory) still being
set, but to nulled values.

Failure of the default Context would therefore leave the
WebContentRunner active but unable to launch any new non-isolated
WebComponents. This affected both the Cast and web Runners.

WebContentRunner & CastRunner are fixed to consume a callback which they
can Run() to get a fresh fuchsia.web.CreateContextParams table from the
caller.

Bug: 1066826, b/152696080
Change-Id: I3610765751c402cd0c3d2acca13c3f0e164f85d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134231
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarDavid Dorwin <ddorwin@chromium.org>
Auto-Submit: Wez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#757011}
parent c684581b
...@@ -102,6 +102,10 @@ void CastComponent::StartComponent() { ...@@ -102,6 +102,10 @@ 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_);
......
...@@ -71,6 +71,8 @@ class CastComponent : public WebComponent, ...@@ -71,6 +71,8 @@ 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:
FRIEND_TEST_ALL_PREFIXES(HeadlessCastRunnerIntegrationTest, Headless); FRIEND_TEST_ALL_PREFIXES(HeadlessCastRunnerIntegrationTest, Headless);
......
This diff is collapsed.
...@@ -29,16 +29,18 @@ class FilteredServiceDirectory; ...@@ -29,16 +29,18 @@ class FilteredServiceDirectory;
// 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 WebContentRunner {
public: public:
using OnDestructionCallback = base::OnceCallback<void(CastRunner*)>; // Creates a Runner for Cast components and publishes it into the specified
// OutgoingDirectory.
// |get_context_params_callback|: Returns the context parameters to use.
// |is_headless|: True if |get_context_params_callback| sets the HEADLESS
// feature flag.
// |outgoing_directory|: The directory that this CastRunner will publish // |outgoing_directory|: The directory that this CastRunner will publish
// itself to. // itself to.
// |context_feature_flags|: The feature flags to use when creating the CastRunner(GetContextParamsCallback get_context_params_callback,
// runner's Context. bool is_headless,
CastRunner(fuchsia::web::CreateContextParams create_context_params,
sys::OutgoingDirectory* outgoing_directory); sys::OutgoingDirectory* outgoing_directory);
~CastRunner() override; ~CastRunner() override;
CastRunner(const CastRunner&) = delete; CastRunner(const CastRunner&) = delete;
CastRunner& operator=(const CastRunner&) = delete; CastRunner& operator=(const CastRunner&) = delete;
...@@ -54,10 +56,15 @@ class CastRunner : public WebContentRunner { ...@@ -54,10 +56,15 @@ class CastRunner : public WebContentRunner {
// Used to connect to the CastAgent to access Cast-specific services. // Used to connect to the CastAgent to access Cast-specific services.
static const char kAgentComponentUrl[]; static const char kAgentComponentUrl[];
// Returns true if this Runner is configured not to use Scenic.
bool is_headless() const { return is_headless_; }
// Returns the number of active CastRunner instances. // Returns the number of active CastRunner instances.
size_t GetChildCastRunnerCountForTest(); size_t GetChildCastRunnerCountForTest();
private: private:
using OnDestructionCallback = base::OnceCallback<void(CastRunner*)>;
// Constructor used for creating CastRunners that run apps in dedicated // Constructor used for creating CastRunners that run apps in dedicated
// Contexts. Child CastRunners may only spawn one Component and will be // Contexts. Child CastRunners may only spawn one Component and will be
// destroyed by their parents when their singleton Components are destroyed. // destroyed by their parents when their singleton Components are destroyed.
...@@ -66,35 +73,43 @@ class CastRunner : public WebContentRunner { ...@@ -66,35 +73,43 @@ class CastRunner : public WebContentRunner {
fuchsia::web::ContextPtr context, fuchsia::web::ContextPtr context,
bool is_headless); bool is_headless);
// Initializes the service directory that's passed to the web context. Must be // Creates and returns the service directory that is passed to the main web
// called during initialization, before the context is created. // context.
void InitializeServiceDirectory(); std::unique_ptr<base::fuchsia::FilteredServiceDirectory>
CreateServiceDirectory();
// Starts a component once all configuration data is available. // Starts a component once all configuration data is available.
void MaybeStartComponent( void MaybeStartComponent(
CastComponent::CastComponentParams* pending_component_params); CastComponent::CastComponentParams* pending_component_params);
// Cancels the launch of a component. // Cancels the launch of a component.
void CancelComponentLaunch(CastComponent::CastComponentParams* params); void CancelComponentLaunch(
CastComponent::CastComponentParams* pending_component_params);
void CreateAndRegisterCastComponent( void CreateAndRegisterCastComponent(
CastComponent::CastComponentParams params); CastComponent::CastComponentParams component_params);
void GetConfigCallback(CastComponent::CastComponentParams* pending_component, void OnApplicationConfigReceived(
chromium::cast::ApplicationConfig app_config); CastComponent::CastComponentParams* pending_component_params,
void GetBindingsCallback( chromium::cast::ApplicationConfig app_config);
CastComponent::CastComponentParams* pending_component,
std::vector<chromium::cast::ApiBinding> bindings);
void OnChildRunnerDestroyed(CastRunner* cast_runner); void OnChildRunnerDestroyed(CastRunner* cast_runner);
// Creates a CastRunner configured to serve data from content directories in // Creates a CastRunner configured to serve data from content directories in
// |params|. Returns nullptr if an error occurred during CastRunner creation. // |params|. Returns nullptr if an error occurred during CastRunner creation.
CastRunner* CreateChildRunnerForIsolatedComponent( CastRunner* CreateChildRunnerForIsolatedComponent(
CastComponent::CastComponentParams* params); CastComponent::CastComponentParams* component_params);
// Handler for fuchsia.media.Audio requests in |service_directory_|. // Handler for fuchsia.media.Audio requests in |service_directory_|.
void ConnectAudioProtocol( void ConnectAudioProtocol(
fidl::InterfaceRequest<fuchsia::media::Audio> request); fidl::InterfaceRequest<fuchsia::media::Audio> 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.
const bool is_headless_;
// Holds StartComponent() requests while the ApplicationConfig is being // Holds StartComponent() requests while the ApplicationConfig is being
// fetched from the ApplicationConfigManager. // fetched from the ApplicationConfigManager.
base::flat_set<std::unique_ptr<CastComponent::CastComponentParams>, base::flat_set<std::unique_ptr<CastComponent::CastComponentParams>,
...@@ -112,7 +127,10 @@ class CastRunner : public WebContentRunner { ...@@ -112,7 +127,10 @@ class CastRunner : public WebContentRunner {
base::flat_set<std::unique_ptr<CastRunner>, base::UniquePtrComparator> base::flat_set<std::unique_ptr<CastRunner>, base::UniquePtrComparator>
isolated_runners_; isolated_runners_;
std::unique_ptr<base::fuchsia::FilteredServiceDirectory> service_directory_; // 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;
......
...@@ -222,16 +222,25 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -222,16 +222,25 @@ class CastRunnerIntegrationTest : public testing::Test {
EnsureFuchsiaDirSchemeInitialized(); EnsureFuchsiaDirSchemeInitialized();
// Create the CastRunner, published into |outgoing_directory_|. // Create the CastRunner, published into |outgoing_directory_|.
fuchsia::web::CreateContextParams create_context_params; WebContentRunner::GetContextParamsCallback get_context_params =
create_context_params.set_features(feature_flags); base::BindLambdaForTesting([feature_flags]() {
create_context_params.set_service_directory(base::fuchsia::OpenDirectory( fuchsia::web::CreateContextParams create_context_params;
base::FilePath(base::fuchsia::kServiceDirectoryPath))); create_context_params.set_features(feature_flags);
CHECK(create_context_params.service_directory()); create_context_params.set_service_directory(
base::fuchsia::OpenDirectory(
const uint16_t kRemoteDebuggingAnyPort = 0; base::FilePath(base::fuchsia::kServiceDirectoryPath)));
create_context_params.set_remote_debugging_port(kRemoteDebuggingAnyPort); CHECK(create_context_params.service_directory());
const uint16_t kRemoteDebuggingAnyPort = 0;
create_context_params.set_remote_debugging_port(
kRemoteDebuggingAnyPort);
return create_context_params;
});
cast_runner_ = std::make_unique<CastRunner>( cast_runner_ = std::make_unique<CastRunner>(
std::move(create_context_params), &outgoing_directory_); std::move(get_context_params),
(feature_flags & fuchsia::web::ContextFeatureFlags::HEADLESS) ==
fuchsia::web::ContextFeatureFlags::HEADLESS,
&outgoing_directory_);
cast_runner_->SetContextProviderForTest(cr_fuchsia::ConnectContextProvider( cast_runner_->SetContextProviderForTest(cr_fuchsia::ConnectContextProvider(
context_provider_controller_.NewRequest())); context_provider_controller_.NewRequest()));
...@@ -257,7 +266,7 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -257,7 +266,7 @@ class CastRunnerIntegrationTest : public testing::Test {
base::StringPiece component_url) { base::StringPiece component_url) {
auto component_state = std::make_unique<FakeComponentState>( auto component_state = std::make_unique<FakeComponentState>(
component_url, &app_config_manager_, &api_bindings_, component_url, &app_config_manager_, &api_bindings_,
&url_request_rewrite_rules_provider_); url_request_rewrite_rules_provider_.get());
component_state_ = component_state.get(); component_state_ = component_state.get();
if (init_component_state_callback_) if (init_component_state_callback_)
...@@ -291,6 +300,8 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -291,6 +300,8 @@ class CastRunnerIntegrationTest : public testing::Test {
} }
void CreateComponentContext(const base::StringPiece& component_url) { void CreateComponentContext(const base::StringPiece& component_url) {
url_request_rewrite_rules_provider_ =
std::make_unique<FakeUrlRequestRewriteRulesProvider>();
component_context_ = std::make_unique<cr_fuchsia::FakeComponentContext>( component_context_ = std::make_unique<cr_fuchsia::FakeComponentContext>(
base::BindRepeating(&CastRunnerIntegrationTest::OnComponentConnect, base::BindRepeating(&CastRunnerIntegrationTest::OnComponentConnect,
base::Unretained(this)), base::Unretained(this)),
...@@ -336,7 +347,7 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -336,7 +347,7 @@ class CastRunnerIntegrationTest : public testing::Test {
} }
void WaitComponentCreated() { void WaitComponentCreated() {
EXPECT_FALSE(cast_component_); ASSERT_FALSE(cast_component_);
base::RunLoop run_loop; base::RunLoop run_loop;
cr_fuchsia::ResultReceiver<WebComponent*> component_receiver( cr_fuchsia::ResultReceiver<WebComponent*> component_receiver(
...@@ -359,13 +370,39 @@ class CastRunnerIntegrationTest : public testing::Test { ...@@ -359,13 +370,39 @@ class CastRunnerIntegrationTest : public testing::Test {
listener.RunUntilUrlAndTitleEquals(url, title); listener.RunUntilUrlAndTitleEquals(url, title);
} }
void WaitForComponentDestroyed() {
ASSERT_TRUE(cast_component_);
ASSERT_TRUE(component_state_);
base::RunLoop state_loop;
component_state_->set_on_delete(state_loop.QuitClosure());
if (component_controller_) {
base::RunLoop controller_loop;
component_controller_.set_error_handler(
[&controller_loop](zx_status_t status) {
EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
controller_loop.Quit();
});
controller_loop.Run();
}
state_loop.Run();
component_context_ = nullptr;
component_services_client_ = nullptr;
component_state_ = nullptr;
cast_component_ = nullptr;
}
base::test::SingleThreadTaskEnvironment task_environment_{ base::test::SingleThreadTaskEnvironment task_environment_{
base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
net::EmbeddedTestServer test_server_; net::EmbeddedTestServer test_server_;
FakeApplicationConfigManager app_config_manager_; FakeApplicationConfigManager app_config_manager_;
TestApiBindings api_bindings_; TestApiBindings api_bindings_;
FakeUrlRequestRewriteRulesProvider url_request_rewrite_rules_provider_; std::unique_ptr<FakeUrlRequestRewriteRulesProvider>
url_request_rewrite_rules_provider_;
// Incoming service directory, ComponentContext and per-component state. // Incoming service directory, ComponentContext and per-component state.
sys::OutgoingDirectory component_services_; sys::OutgoingDirectory component_services_;
...@@ -414,10 +451,41 @@ TEST_F(CastRunnerIntegrationTest, BasicRequest) { ...@@ -414,10 +451,41 @@ TEST_F(CastRunnerIntegrationTest, BasicRequest) {
// Verify that the component is torn down when |component_controller| is // Verify that the component is torn down when |component_controller| is
// unbound. // unbound.
base::RunLoop run_loop;
component_state_->set_on_delete(run_loop.QuitClosure());
component_controller_.Unbind(); component_controller_.Unbind();
run_loop.Run(); WaitForComponentDestroyed();
}
// Verify that the Runner can continue to be used even after its Context has
// crashed. Regression test for https://crbug.com/1066826).
// TODO(https://crbug.com/1066833): Make this a WebRunner test.
TEST_F(CastRunnerIntegrationTest, CanRecreateContext) {
// Execute two iterations of launching the component and verifying that it
// reaches the expected URL.
for (int i = 0; i < 2; ++i) {
const GURL app_url = test_server_.GetURL(kBlankAppUrl);
app_config_manager_.AddApp(kTestAppId, app_url);
CreateComponentContextAndStartComponent();
fuchsia::web::NavigationControllerPtr nav_controller;
cast_component_->frame()->GetNavigationController(
nav_controller.NewRequest());
base::RunLoop run_loop;
cr_fuchsia::ResultReceiver<fuchsia::web::NavigationState> nav_entry(
run_loop.QuitClosure());
nav_controller->GetVisibleEntry(
cr_fuchsia::CallbackToFitFunction(nav_entry.GetReceiveCallback()));
run_loop.Run();
ASSERT_TRUE(nav_entry->has_url());
EXPECT_EQ(nav_entry->url(), app_url.spec());
// Fake teardown of the Context, forcing the next StartComponent to create
// a new one.
cast_runner_->DisconnectContextForTest();
WaitForComponentDestroyed();
}
} }
TEST_F(CastRunnerIntegrationTest, ApiBindings) { TEST_F(CastRunnerIntegrationTest, ApiBindings) {
...@@ -562,10 +630,8 @@ TEST_F(CastRunnerIntegrationTest, IsolatedContext) { ...@@ -562,10 +630,8 @@ TEST_F(CastRunnerIntegrationTest, IsolatedContext) {
// Verify that the component is torn down when |component_controller| is // Verify that the component is torn down when |component_controller| is
// unbound. // unbound.
base::RunLoop run_loop;
component_state_->set_on_delete(run_loop.QuitClosure());
component_controller_.Unbind(); component_controller_.Unbind();
run_loop.Run(); WaitForComponentDestroyed();
EXPECT_EQ(cast_runner_->GetChildCastRunnerCountForTest(), 0u); EXPECT_EQ(cast_runner_->GetChildCastRunnerCountForTest(), 0u);
} }
...@@ -787,10 +853,8 @@ TEST_F(HeadlessCastRunnerIntegrationTest, IsolatedAndHeadless) { ...@@ -787,10 +853,8 @@ TEST_F(HeadlessCastRunnerIntegrationTest, IsolatedAndHeadless) {
// Verify that the component is torn down when |component_controller| is // Verify that the component is torn down when |component_controller| is
// unbound. // unbound.
base::RunLoop run_loop;
component_state_->set_on_delete(run_loop.QuitClosure());
component_controller_.Unbind(); component_controller_.Unbind();
run_loop.Run(); WaitForComponentDestroyed();
EXPECT_EQ(cast_runner_->GetChildCastRunnerCountForTest(), 0u); EXPECT_EQ(cast_runner_->GetChildCastRunnerCountForTest(), 0u);
} }
...@@ -54,6 +54,6 @@ void FakeApplicationConfigManager::GetConfig(std::string id, ...@@ -54,6 +54,6 @@ void FakeApplicationConfigManager::GetConfig(std::string id,
return; return;
} }
callback(std::move(std::move(id_to_config_[id]))); callback(std::move(id_to_config_[id]));
id_to_config_.erase(id); id_to_config_.erase(id);
} }
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#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/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"
...@@ -33,19 +34,7 @@ bool IsHeadless() { ...@@ -33,19 +34,7 @@ bool IsHeadless() {
return false; return false;
} }
} // namespace fuchsia::web::CreateContextParams CreateMainContextParams() {
int main(int argc, char** argv) {
base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
base::CommandLine::Init(argc, argv);
CHECK(cr_fuchsia::InitLoggingFromCommandLine(
*base::CommandLine::ForCurrentProcess()))
<< "Failed to initialize logging.";
cr_fuchsia::RegisterFuchsiaDirScheme();
fuchsia::web::ContextFeatureFlags features = fuchsia::web::ContextFeatureFlags features =
fuchsia::web::ContextFeatureFlags::NETWORK | fuchsia::web::ContextFeatureFlags::NETWORK |
fuchsia::web::ContextFeatureFlags::AUDIO | fuchsia::web::ContextFeatureFlags::AUDIO |
...@@ -82,8 +71,27 @@ int main(int argc, char** argv) { ...@@ -82,8 +71,27 @@ int main(int argc, char** argv) {
create_context_params.set_unsafely_treat_insecure_origins_as_secure( create_context_params.set_unsafely_treat_insecure_origins_as_secure(
{"allow-running-insecure-content"}); {"allow-running-insecure-content"});
return create_context_params;
}
} // namespace
int main(int argc, char** argv) {
base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
base::CommandLine::Init(argc, argv);
CHECK(cr_fuchsia::InitLoggingFromCommandLine(
*base::CommandLine::ForCurrentProcess()))
<< "Failed to initialize logging.";
cr_fuchsia::RegisterFuchsiaDirScheme();
WebContentRunner::GetContextParamsCallback get_context_params_callback =
base::BindRepeating(&CreateMainContextParams);
CastRunner runner( CastRunner runner(
std::move(create_context_params), std::move(get_context_params_callback), IsHeadless(),
base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get()); base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get());
base::fuchsia::ComponentContextForCurrentProcess() base::fuchsia::ComponentContextForCurrentProcess()
......
...@@ -23,25 +23,21 @@ ...@@ -23,25 +23,21 @@
#include "url/gurl.h" #include "url/gurl.h"
WebContentRunner::WebContentRunner( WebContentRunner::WebContentRunner(
fuchsia::web::CreateContextParams create_params, GetContextParamsCallback get_context_params_callback,
sys::OutgoingDirectory* outgoing_directory) sys::OutgoingDirectory* outgoing_directory)
: create_params_(std::move(create_params)), : get_context_params_callback_(std::move(get_context_params_callback)) {
is_headless_((create_params_.features() &
fuchsia::web::ContextFeatureFlags::HEADLESS) ==
fuchsia::web::ContextFeatureFlags::HEADLESS) {
service_binding_.emplace(outgoing_directory, this); service_binding_.emplace(outgoing_directory, this);
} }
WebContentRunner::WebContentRunner(fuchsia::web::ContextPtr context, WebContentRunner::WebContentRunner(fuchsia::web::ContextPtr context)
bool is_headless) : context_(std::move(context)) {}
: context_(std::move(context)), is_headless_(is_headless) {}
WebContentRunner::~WebContentRunner() = default; WebContentRunner::~WebContentRunner() = default;
fuchsia::web::ContextPtr WebContentRunner::CreateWebContext( fuchsia::web::ContextPtr WebContentRunner::CreateWebContext(
fuchsia::web::CreateContextParams create_params) { fuchsia::web::CreateContextParams context_params) {
fuchsia::web::ContextPtr web_context; fuchsia::web::ContextPtr web_context;
GetContextProvider()->Create(std::move(create_params), GetContextProvider()->Create(std::move(context_params),
web_context.NewRequest()); web_context.NewRequest());
web_context.set_error_handler([](zx_status_t status) { web_context.set_error_handler([](zx_status_t status) {
// If the browser instance died, then exit everything and do not attempt to // If the browser instance died, then exit everything and do not attempt to
...@@ -54,8 +50,7 @@ fuchsia::web::ContextPtr WebContentRunner::CreateWebContext( ...@@ -54,8 +50,7 @@ fuchsia::web::ContextPtr WebContentRunner::CreateWebContext(
fuchsia::web::Context* WebContentRunner::GetContext() { fuchsia::web::Context* WebContentRunner::GetContext() {
if (!context_) if (!context_)
context_ = CreateWebContext(std::move(create_params_)); context_ = CreateWebContext(get_context_params_callback_.Run());
return context_.get(); return context_.get();
} }
...@@ -106,6 +101,10 @@ void WebContentRunner::SetContextProviderForTest( ...@@ -106,6 +101,10 @@ void WebContentRunner::SetContextProviderForTest(
context_provider_ = std::move(context_provider); context_provider_ = std::move(context_provider);
} }
void WebContentRunner::DisconnectContextForTest() {
context_.Unbind();
}
fuchsia::web::ContextProvider* WebContentRunner::GetContextProvider() { fuchsia::web::ContextProvider* WebContentRunner::GetContextProvider() {
if (!context_provider_) { if (!context_provider_) {
context_provider_ = base::fuchsia::ComponentContextForCurrentProcess() context_provider_ = base::fuchsia::ComponentContextForCurrentProcess()
......
...@@ -22,23 +22,29 @@ class WebComponent; ...@@ -22,23 +22,29 @@ class WebComponent;
// sys::Runner that instantiates components hosting standard web content. // sys::Runner that instantiates components hosting standard web content.
class WebContentRunner : public fuchsia::sys::Runner { class WebContentRunner : public fuchsia::sys::Runner {
public: public:
using CreateContextCallback = base::OnceCallback<fuchsia::web::ContextPtr()>; using GetContextParamsCallback =
base::RepeatingCallback<fuchsia::web::CreateContextParams()>;
// |create_params|: Parameters to use for the Runner's web.Context. // Creates a Runner for web-based components, and publishes it to the
// specified OutgoingDirectory.
// |get_context_params_callback|: Returns parameters for the Runner's
// web.Context.
// |outgoing_directory|: The directory that the Runner's services will be // |outgoing_directory|: The directory that the Runner's services will be
// published to. // published to.
WebContentRunner(fuchsia::web::CreateContextParams create_params, WebContentRunner(GetContextParamsCallback get_context_params_callback,
sys::OutgoingDirectory* outgoing_directory); sys::OutgoingDirectory* outgoing_directory);
// Alternative constructor for unpublished Runners. // Creates a Runner which launches components using the specified |context|.
explicit WebContentRunner(fuchsia::web::ContextPtr context, bool is_headless); // The caller may publish the Runner, or call StartComponent() manually to
// create new components with it.
explicit WebContentRunner(fuchsia::web::ContextPtr context);
~WebContentRunner() override; ~WebContentRunner() override;
// TODO(crbug.com/1046615): Make this static when the injected ContextProvider // TODO(crbug.com/1046615): Make this static when the injected ContextProvider
// goes away. // goes away.
fuchsia::web::ContextPtr CreateWebContext( fuchsia::web::ContextPtr CreateWebContext(
fuchsia::web::CreateContextParams create_params); fuchsia::web::CreateContextParams context_params);
// Gets a pointer to this runner's Context, creating one if needed. // Gets a pointer to this runner's Context, creating one if needed.
fuchsia::web::Context* GetContext(); fuchsia::web::Context* GetContext();
...@@ -47,9 +53,6 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -47,9 +53,6 @@ class WebContentRunner : public fuchsia::sys::Runner {
// 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); virtual void DestroyComponent(WebComponent* component);
// Set if Cast applications are to be run without graphical rendering.
bool is_headless() const { return is_headless_; }
// 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,
...@@ -68,17 +71,20 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -68,17 +71,20 @@ class WebContentRunner : public fuchsia::sys::Runner {
void SetContextProviderForTest( void SetContextProviderForTest(
fuchsia::web::ContextProviderPtr context_provider); fuchsia::web::ContextProviderPtr context_provider);
// Disconnects the Context used by this Runner.
void DisconnectContextForTest();
protected: protected:
base::RepeatingCallback<void(WebComponent*)> base::RepeatingCallback<void(WebComponent*)>
web_component_created_callback_for_test() const { web_component_created_callback_for_test() const {
return web_component_created_callback_for_test_; return web_component_created_callback_for_test_;
} }
fuchsia::web::CreateContextParams create_params_;
private: private:
fuchsia::web::ContextProvider* GetContextProvider(); fuchsia::web::ContextProvider* GetContextProvider();
const GetContextParamsCallback get_context_params_callback_;
// If set, invoked whenever a WebComponent is created. // If set, invoked whenever a WebComponent is created.
base::RepeatingCallback<void(WebComponent*)> base::RepeatingCallback<void(WebComponent*)>
web_component_created_callback_for_test_; web_component_created_callback_for_test_;
...@@ -87,7 +93,6 @@ class WebContentRunner : public fuchsia::sys::Runner { ...@@ -87,7 +93,6 @@ class WebContentRunner : public fuchsia::sys::Runner {
fuchsia::web::ContextPtr context_; fuchsia::web::ContextPtr context_;
std::set<std::unique_ptr<WebComponent>, base::UniquePtrComparator> std::set<std::unique_ptr<WebComponent>, base::UniquePtrComparator>
components_; components_;
const bool is_headless_;
// Publishes this Runner into the service directory specified at construction. // Publishes this Runner into the service directory specified at construction.
// This is not set for child runner instances. // This is not set for child runner instances.
......
...@@ -15,17 +15,9 @@ ...@@ -15,17 +15,9 @@
#include "fuchsia/runners/buildflags.h" #include "fuchsia/runners/buildflags.h"
#include "fuchsia/runners/common/web_content_runner.h" #include "fuchsia/runners/common/web_content_runner.h"
int main(int argc, char** argv) { namespace {
base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
base::CommandLine::Init(argc, argv);
CHECK(cr_fuchsia::InitLoggingFromCommandLine(
*base::CommandLine::ForCurrentProcess()))
<< "Failed to initialize logging.";
cr_fuchsia::RegisterFuchsiaDirScheme();
fuchsia::web::CreateContextParams GetContextParams() {
fuchsia::web::CreateContextParams create_context_params; fuchsia::web::CreateContextParams create_context_params;
create_context_params.set_features( create_context_params.set_features(
fuchsia::web::ContextFeatureFlags::NETWORK | fuchsia::web::ContextFeatureFlags::NETWORK |
...@@ -46,9 +38,27 @@ int main(int argc, char** argv) { ...@@ -46,9 +38,27 @@ int main(int argc, char** argv) {
create_context_params.set_remote_debugging_port( create_context_params.set_remote_debugging_port(
BUILDFLAG(WEB_RUNNER_REMOTE_DEBUGGING_PORT)); BUILDFLAG(WEB_RUNNER_REMOTE_DEBUGGING_PORT));
#endif #endif
return create_context_params;
}
} // namespace
int main(int argc, char** argv) {
base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
base::CommandLine::Init(argc, argv);
CHECK(cr_fuchsia::InitLoggingFromCommandLine(
*base::CommandLine::ForCurrentProcess()))
<< "Failed to initialize logging.";
cr_fuchsia::RegisterFuchsiaDirScheme();
WebContentRunner::GetContextParamsCallback get_context_params_callback =
base::BindRepeating(&GetContextParams);
WebContentRunner runner( WebContentRunner runner(
std::move(create_context_params), std::move(get_context_params_callback),
base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get()); base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get());
base::fuchsia::ComponentContextForCurrentProcess() base::fuchsia::ComponentContextForCurrentProcess()
......
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