blob: 541f74dcffa4aba2dc49016ac2e4e4e85d148b65 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 SRC_MODULAR_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_
#define SRC_MODULAR_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_
#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/internal/cpp/fidl.h>
#include <fuchsia/session/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fit/function.h>
#include <lib/sys/inspect/cpp/component.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include "lib/vfs/cpp/pseudo_dir.h"
#include "src/lib/fxl/macros.h"
#include "src/modular/bin/sessionmgr/agent_runner/agent_runner.h"
#include "src/modular/bin/sessionmgr/argv_injecting_launcher.h"
#include "src/modular/bin/sessionmgr/component_context_impl.h"
#include "src/modular/bin/sessionmgr/element_manager_impl.h"
#include "src/modular/bin/sessionmgr/puppet_master/puppet_master_impl.h"
#include "src/modular/bin/sessionmgr/puppet_master/story_command_executor.h"
#include "src/modular/bin/sessionmgr/session_ctl.h"
#include "src/modular/bin/sessionmgr/startup_agent_launcher.h"
#include "src/modular/bin/sessionmgr/storage/session_storage.h"
#include "src/modular/bin/sessionmgr/storage/story_storage.h"
#include "src/modular/bin/sessionmgr/story_runner/story_provider_impl.h"
#include "src/modular/lib/common/async_holder.h"
#include "src/modular/lib/deprecated_service_provider/service_provider_impl.h"
#include "src/modular/lib/fidl/app_client.h"
#include "src/modular/lib/fidl/environment.h"
#include "src/modular/lib/modular_config/modular_config_accessor.h"
#include "src/modular/lib/scoped_tmpfs/scoped_tmpfs.h"
namespace modular {
class SessionmgrImpl : fuchsia::modular::internal::Sessionmgr,
fuchsia::modular::SessionShellContext,
public fuchsia::modular::SessionRestartController {
public:
SessionmgrImpl(sys::ComponentContext* component_context, modular::ModularConfigAccessor config,
inspect::Node object);
~SessionmgrImpl() override;
// |AppDriver| calls this.
void Terminate(fit::function<void()> done);
private:
// |Sessionmgr|
void Initialize(std::string session_id,
fidl::InterfaceHandle<fuchsia::modular::internal::SessionContext> session_context,
fuchsia::sys::ServiceList v2_services_for_sessionmgr,
fidl::InterfaceRequest<fuchsia::io::Directory> svc_from_v1_sessionmgr,
fuchsia::ui::views::ViewToken view_token,
fuchsia::ui::views::ViewRefControl control_ref,
fuchsia::ui::views::ViewRef view_ref) override;
// Sequence of Initialize() broken up into steps for clarity.
void InitializeSessionEnvironment(std::string session_id);
void InitializeStartupAgentLauncher(fuchsia::sys::ServiceList v2_services_for_sessionmgr);
void InitializeStartupAgents();
void InitializeAgentRunner(const std::string& session_shell_url);
void InitializeStoryProvider(fuchsia::modular::session::AppConfig story_shell_config,
bool use_session_shell_for_story_shell_factory);
void InitializeSessionShell(fuchsia::modular::session::AppConfig session_shell_config,
fuchsia::ui::views::ViewToken view_token,
scenic::ViewRefPair view_ref_pair);
void InitializePuppetMaster();
void InitializeElementManager();
void InitializeSessionCtl();
void ServeSvcFromV1SessionmgrDir(
fidl::InterfaceRequest<fuchsia::io::Directory> svc_from_v1_sessionmgr);
// |fuchsia::modular::SessionShellContext|
void GetComponentContext(
fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) override;
void GetPresentation(fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) override;
void GetStoryProvider(fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) override;
void Logout() override;
void Restart() override;
void RestartDueToCriticalFailure();
// Called during initialization. Schedules the given action to be executed
// during termination. This allows to create something like an asynchronous
// destructor at initialization time. The sequence of actions thus scheduled
// is executed in reverse in Terminate().
//
// The OnTerminate() calls for a field should happen next to the calls that
// initialize the field, for the following reasons:
//
// 1. It ensures the termination sequence corresponds to the initialization
// sequence.
//
// 2. It is easy to audit that there is a termination action for every
// initialization that needs one.
//
// 3. Conditional initialization also omits the termination (such as for
// agents that are not started when runnign a test).
//
// See also the Reset() and Teardown() functions in the .cc file.
void OnTerminate(fit::function<void(fit::function<void()>)> action);
// Recursively execute the termiation steps scheduled by OnTerminate(). The
// execution steps are stored in on_terminate_cbs_.
void TerminateRecurse(int i);
void ConnectSessionShellToStoryProvider();
// Connects to service Interface from the session shell. If the shell is not
// running, closes the request.
template <class Interface>
void ConnectToSessionShellService(fidl::InterfaceRequest<Interface> request) {
auto services = agent_runner_->GetAgentOutgoingServices(session_shell_url_);
if (!services) {
return;
}
services->ConnectToService(std::move(request));
}
// The device-local unique identifier for this session. The uniqueness
// is enforced by basemgr which vends sessions.
std::string session_id_;
// The context in which the Sessionmgr was launched
sys::ComponentContext* const sessionmgr_context_;
// The Sessionmgr creates a new environment as a child of its component context's environment.
// Story shells and mods are launched within the |session_environment_|. Other services are
// launched outside of the |session_environment_| (and in the sessionmgr_context_ environment).
// **NOTE: Agents, logically, should be in the |session_environment_| as well, but for legacy
// reasons due to hard dependencies on a /data path that does not have "session" uniqueness,
// Agents are launched in the |sessionmgr_context_| environment as well. Since Modular services
// like this will only support one session anyway, this is acceptable for now, and will be
// resolved in Session Framework (replacing Modular).
std::unique_ptr<Environment> session_environment_;
modular::ModularConfigAccessor config_accessor_;
inspect::Node inspect_root_node_;
fidl::BindingSet<fuchsia::modular::internal::Sessionmgr> bindings_;
component::ServiceProviderImpl session_shell_services_;
std::string session_shell_url_;
fidl::BindingSet<fuchsia::modular::SessionShellContext> session_shell_context_bindings_;
fidl::BindingSet<fuchsia::modular::SessionRestartController> session_restart_controller_bindings_;
fuchsia::modular::internal::SessionContextPtr session_context_;
std::unique_ptr<SessionStorage> session_storage_;
AsyncHolder<StoryProviderImpl> story_provider_impl_;
std::unique_ptr<ArgvInjectingLauncher> agent_runner_launcher_;
AsyncHolder<AgentRunner> agent_runner_;
vfs::PseudoDir svc_from_v1_sessionmgr_dir_;
std::unique_ptr<StoryCommandExecutor> story_command_executor_;
std::unique_ptr<PuppetMasterImpl> puppet_master_impl_;
std::unique_ptr<ElementManagerImpl> element_manager_impl_;
std::unique_ptr<SessionCtl> session_ctl_;
std::unique_ptr<StartupAgentLauncher> startup_agent_launcher_;
// Component context given to session shell so that it can run agents.
std::unique_ptr<ComponentContextImpl> session_shell_component_context_impl_;
// Given to the session shell so it can store its own data. These data are
// shared between all session shells (so it's not private to the session shell
// *app*).
std::unique_ptr<StoryStorage> session_shell_storage_;
// Holds the actions scheduled by calls to the OnTerminate() method.
std::vector<fit::function<void(fit::function<void()>)>> on_terminate_cbs_;
// Holds the done callback of Terminate() while the on_terminate_cbs_ actions are being
// executed.
fit::function<void()> terminate_done_;
struct UIHandlers {
fuchsia::modular::SessionShellPtr session_shell;
fuchsia::element::GraphicalPresenterPtr graphical_presenter;
};
// Contains connections to view presentation protocols.
UIHandlers ui_handlers_;
OperationQueue operation_queue_;
// Set to |true| when sessionmgr starts its terminating sequence; this flag
// can be used to determine whether to reject vending FIDL services.
bool terminating_ = false;
FXL_DISALLOW_COPY_AND_ASSIGN(SessionmgrImpl);
fxl::WeakPtrFactory<SessionmgrImpl> weak_ptr_factory_;
};
} // namespace modular
#endif // SRC_MODULAR_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_