| // Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_FUCHSIA_COMPONENT_V2_H_ |
| #define FLUTTER_SHELL_PLATFORM_FUCHSIA_COMPONENT_V2_H_ |
| |
| #include <array> |
| #include <memory> |
| #include <set> |
| |
| #include <fuchsia/component/runner/cpp/fidl.h> |
| #include <fuchsia/io/cpp/fidl.h> |
| #include <fuchsia/ui/app/cpp/fidl.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/async/default.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/fidl/cpp/interface_request.h> |
| #include <lib/fit/function.h> |
| #include <lib/sys/cpp/service_directory.h> |
| #include <lib/vfs/cpp/pseudo_dir.h> |
| #include <lib/zx/eventpair.h> |
| |
| #include "flutter/common/settings.h" |
| #include "flutter/fml/macros.h" |
| |
| #include "engine.h" |
| #include "flutter_runner_product_configuration.h" |
| #include "program_metadata.h" |
| #include "unique_fdio_ns.h" |
| |
| namespace flutter_runner { |
| |
| class ComponentV2; |
| |
| struct ActiveComponentV2 { |
| std::unique_ptr<fml::Thread> platform_thread; |
| std::unique_ptr<ComponentV2> component; |
| |
| ActiveComponentV2& operator=(ActiveComponentV2&& other) noexcept { |
| if (this != &other) { |
| this->platform_thread.reset(other.platform_thread.release()); |
| this->component.reset(other.component.release()); |
| } |
| return *this; |
| } |
| |
| ~ActiveComponentV2() = default; |
| }; |
| |
| // Represents an instance of a CF v2 Flutter component that contains one or more |
| // Flutter engine instances. |
| // |
| // TODO(fxb/50694): Add unit tests once we've verified that the current behavior |
| // is working correctly. |
| class ComponentV2 final |
| : public Engine::Delegate, |
| public fuchsia::component::runner::ComponentController, |
| public fuchsia::ui::app::ViewProvider { |
| public: |
| using TerminationCallback = fit::function<void(const ComponentV2*)>; |
| |
| // Creates a dedicated thread to run the component and creates the |
| // component on it. The component can be accessed only on this thread. |
| // This is a synchronous operation. |
| static ActiveComponentV2 Create( |
| TerminationCallback termination_callback, |
| fuchsia::component::runner::ComponentStartInfo start_info, |
| std::shared_ptr<sys::ServiceDirectory> runner_incoming_services, |
| fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> |
| controller); |
| |
| // Must be called on the same thread returned from the create call. The thread |
| // may be collected after. |
| ~ComponentV2(); |
| |
| /// Parses the program metadata that was provided for the component. |
| /// |
| /// |old_gen_heap_size| will be set to -1 if no value was specified. |
| static ProgramMetadata ParseProgramMetadata( |
| const fuchsia::data::Dictionary& program_metadata); |
| |
| const std::string& GetDebugLabel() const; |
| |
| #if !defined(DART_PRODUCT) |
| void WriteProfileToTrace() const; |
| #endif // !defined(DART_PRODUCT) |
| |
| private: |
| ComponentV2( |
| TerminationCallback termination_callback, |
| fuchsia::component::runner::ComponentStartInfo start_info, |
| std::shared_ptr<sys::ServiceDirectory> runner_incoming_services, |
| fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> |
| controller); |
| |
| // |fuchsia::component::runner::ComponentController| |
| void Kill() override; |
| |
| /// Helper to actually |Kill| the component, closing the connection via an |
| /// epitaph with the given |epitaph_status|. Call this instead of |
| /// Kill() in the implementation of this class, as |Kill| is only intended for |
| /// clients of the ComponentController protocol to call. |
| /// |
| /// To determine what |epitaph_status| is appropriate for your situation, |
| /// see the documentation for |fuchsia.component.runner.ComponentController|. |
| void KillWithEpitaph(zx_status_t epitaph_status); |
| |
| // |fuchsia::component::runner::ComponentController| |
| void Stop() override; |
| |
| // |fuchsia::ui::app::ViewProvider| |
| void CreateView2(fuchsia::ui::app::CreateView2Args view_args) override; |
| |
| // |flutter::Engine::Delegate| |
| void OnEngineTerminate(const Engine* holder) override; |
| |
| flutter::Settings settings_; |
| FlutterRunnerProductConfiguration product_config_; |
| TerminationCallback termination_callback_; |
| const std::string debug_label_; |
| UniqueFDIONS fdio_ns_ = UniqueFDIONSCreate(); |
| fml::UniqueFD component_data_directory_; |
| fml::UniqueFD component_assets_directory_; |
| |
| fidl::Binding<fuchsia::component::runner::ComponentController> |
| component_controller_; |
| fuchsia::io::DirectoryPtr directory_ptr_; |
| fuchsia::io::NodePtr cloned_directory_ptr_; |
| fidl::InterfaceRequest<fuchsia::io::Directory> directory_request_; |
| std::unique_ptr<vfs::PseudoDir> outgoing_dir_; |
| std::unique_ptr<vfs::PseudoDir> runtime_dir_; |
| std::shared_ptr<sys::ServiceDirectory> svc_; |
| std::shared_ptr<sys::ServiceDirectory> runner_incoming_services_; |
| fidl::BindingSet<fuchsia::ui::app::ViewProvider> shells_bindings_; |
| |
| fml::RefPtr<flutter::DartSnapshot> isolate_snapshot_; |
| std::set<std::unique_ptr<Engine>> shell_holders_; |
| std::pair<bool, uint32_t> last_return_code_; |
| fml::WeakPtrFactory<ComponentV2> weak_factory_; // Must be the last member. |
| FML_DISALLOW_COPY_AND_ASSIGN(ComponentV2); |
| }; |
| |
| } // namespace flutter_runner |
| |
| #endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_COMPONENT_V2_H_ |