| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_ |
| #define FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_ |
| |
| #include <chromium/cast/cpp/fidl.h> |
| #include <fuchsia/component/runner/cpp/fidl.h> |
| #include <fuchsia/web/cpp/fidl.h> |
| |
| #include <memory> |
| #include <set> |
| #include <vector> |
| |
| #include "base/containers/flat_set.h" |
| #include "base/containers/unique_ptr_adapters.h" |
| #include "base/fuchsia/startup_context.h" |
| #include "base/functional/callback.h" |
| #include "fuchsia_web/runners/cast/cast_component.h" |
| #include "fuchsia_web/runners/cast/pending_cast_component.h" |
| #include "fuchsia_web/runners/common/web_content_runner.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| class WebInstanceHost; |
| |
| // ComponentRunner that runs Cast activities specified via cast/casts URIs. |
| class CastRunner final : public fuchsia::component::runner::ComponentRunner, |
| public chromium::cast::DataReset, |
| public PendingCastComponent::Delegate { |
| public: |
| struct Options { |
| // Set to true to run components without generating output via Scenic. |
| bool headless = false; |
| |
| // Set to true to run components without without web optimizations (e.g. |
| // JavaScript Just-In-Time compilation) or features (e.g. WebAssembly) that |
| // require dynamic code generation. |
| bool disable_codegen = false; |
| }; |
| |
| static constexpr uint16_t kRemoteDebuggingPort = 9222; |
| |
| // Creates the Runner for Cast components. |
| // `web_instance_host` is used to create a "main" instance to host Cast apps |
| // and serve `FrameHost` instances, and isolated containers for apps that |
| // need them. |
| CastRunner(WebInstanceHost& web_instance_host, Options options); |
| ~CastRunner() override; |
| |
| CastRunner(const CastRunner&) = delete; |
| CastRunner& operator=(const CastRunner&) = delete; |
| |
| // fuchsia::component::runner::ComponentRunner implementation. |
| void Start( |
| fuchsia::component::runner::ComponentStartInfo start_info, |
| fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> |
| controller) override; |
| |
| // chromium::cast::DataReset implementation. |
| void DeletePersistentData(DeletePersistentDataCallback callback) override; |
| |
| // Returns a connection request handler for the fuchsia.web.FrameHost |
| // protocol exposed by the main web_instance. |
| fidl::InterfaceRequestHandler<fuchsia::web::FrameHost> |
| GetFrameHostRequestHandler(); |
| |
| // Disables use of the VULKAN feature when creating Contexts. Must be set |
| // before calling StartComponent(). |
| void set_disable_vulkan_for_test() { disable_vulkan_for_test_ = true; } |
| |
| private: |
| // PendingCastComponent::Delegate implementation. |
| void LaunchPendingComponent(PendingCastComponent* pending_component, |
| CastComponent::Params params) override; |
| void CancelPendingComponent(PendingCastComponent* pending_component) override; |
| |
| // Handlers used to provide parameters for main & isolated Contexts. |
| WebContentRunner::WebInstanceConfig GetCommonWebInstanceConfig(); |
| WebContentRunner::WebInstanceConfig GetMainWebInstanceConfig(); |
| WebContentRunner::WebInstanceConfig |
| GetIsolatedWebInstanceConfigWithFuchsiaDirs( |
| std::vector<fuchsia::web::ContentDirectoryProvider> content_directories); |
| // TODO(crbug.com/1082821): Remove this once the CastStreamingReceiver |
| // Component has been implemented. |
| WebContentRunner::WebInstanceConfig |
| GetIsolatedWebInstanceConfigForCastStreaming(); |
| |
| // Returns CreateContextParams for |app_config|. Returns nullopt if there is |
| // no need to create an isolated context. |
| absl::optional<WebContentRunner::WebInstanceConfig> |
| GetWebInstanceConfigForAppConfig( |
| chromium::cast::ApplicationConfig* app_config); |
| |
| // Launches an isolated Context with the given `config` and returns the newly |
| // created WebContentRunner. |
| WebContentRunner* CreateIsolatedRunner( |
| WebContentRunner::WebInstanceConfig config); |
| |
| // Called when an isolated component terminates, to allow the Context hosting |
| // it to be torn down. |
| void OnIsolatedContextEmpty(WebContentRunner* context); |
| |
| // Internal implementation of StartComponent(), called after validating the |
| // component URL and ensuring that CORS-exempt headers have been fetched. |
| void StartComponentInternal( |
| const GURL& url, |
| std::unique_ptr<base::StartupContext> startup_context, |
| fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> |
| controller_request); |
| |
| // Moves all data persisted by the main Context to a staging directory, |
| // which will be deleted the next time the Runner starts up, and configures |
| // the Runner to reject new component-launch requests until it is shutdown. |
| // Returns false if tha data directory cannot be cleaned-up. |
| bool DeletePersistentDataInternal(); |
| |
| // TODO(crbug.com/1188780): Used to detect when the persisted cache directory |
| // was erased. The sentinel file is created at the top-level of the cache |
| // directory, so cannot be deleted by the Context, only by the cache being |
| // erased. |
| void CreatePersistedCacheSentinel(); |
| bool WasPersistedCacheErased(); |
| |
| // Passed to WebContentRunners to use to create web_instance Components. |
| const raw_ref<WebInstanceHost> web_instance_host_; |
| |
| // True if this Runner uses Context(s) with the HEADLESS feature set. |
| const bool is_headless_; |
| |
| // True if this Runner should create web Contexts with dynamic code generation |
| // disabled. |
| const bool disable_codegen_; |
| |
| // 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<WebContentRunner> main_context_; |
| |
| // Holds `fuchsia.web.Context`s used to host isolated components. |
| base::flat_set<std::unique_ptr<WebContentRunner>, base::UniquePtrComparator> |
| isolated_contexts_; |
| |
| // Temporarily holds a PendingCastComponent instance, responsible for fetching |
| // the parameters required to launch the component, for each call to |
| // StartComponent(). |
| base::flat_set<std::unique_ptr<PendingCastComponent>, |
| base::UniquePtrComparator> |
| pending_components_; |
| |
| // Used to fetch & cache the list of CORS exempt HTTP headers to configure |
| // each web.Context with. |
| absl::optional<std::vector<std::vector<uint8_t>>> cors_exempt_headers_; |
| chromium::cast::CorsExemptHeaderProviderPtr cors_exempt_headers_provider_; |
| std::vector<base::OnceClosure> on_have_cors_exempt_headers_; |
| |
| // True if Contexts should be created without VULKAN set. |
| bool disable_vulkan_for_test_ = false; |
| |
| // True if cast runner entered data reset mode. Prevents new components |
| // in the main context from being launched. This is set to true once data |
| // reset starts and does not switch back to false upon completion. |
| bool data_reset_in_progress_ = false; |
| |
| // True if the cache sentinel file should exist. |
| // TODO(crbug.com/1188780): Remove once an explicit cache flush signal exists. |
| bool was_cache_sentinel_created_ = false; |
| }; |
| |
| #endif // FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_ |