[sessionmgr] allow overriding the cloud provider for Voila

This patch allows to pass sessionmgr a flag that makes it use the cloud
provider from incoming service namespace, rather than spinning up its
own. This allows the app that starts sessionmgr to override the cloud
provider – in particular, this allows Voila to override it.

LE-663

Change-Id: I9d705f9abe9d3cc2b473faa1df68194928d24f8a
diff --git a/peridot/bin/sessionmgr/sessionmgr.cc b/peridot/bin/sessionmgr/sessionmgr.cc
index 384a212..9d9cf85 100644
--- a/peridot/bin/sessionmgr/sessionmgr.cc
+++ b/peridot/bin/sessionmgr/sessionmgr.cc
@@ -34,6 +34,8 @@
   opts.use_memfs_for_ledger = command_line.HasOption("use_memfs_for_ledger");
   opts.no_cloud_provider_for_ledger =
       command_line.HasOption("no_cloud_provider_for_ledger");
+  opts.use_cloud_provider_from_environment =
+      command_line.HasOption("use_cloud_provider_from_environment");
 
   async::Loop loop(&kAsyncLoopConfigAttachToThread);
   trace::TraceProvider trace_provider(loop.dispatcher());
diff --git a/peridot/bin/sessionmgr/sessionmgr_impl.cc b/peridot/bin/sessionmgr/sessionmgr_impl.cc
index a21c6aa..931fe11 100644
--- a/peridot/bin/sessionmgr/sessionmgr_impl.cc
+++ b/peridot/bin/sessionmgr/sessionmgr_impl.cc
@@ -290,20 +290,17 @@
   fuchsia::ledger::cloud::CloudProviderPtr cloud_provider;
   std::string ledger_user_id;
   if (account_ && !options_.no_cloud_provider_for_ledger) {
-    // If not running in Guest mode, spin up a cloud provider for Ledger to use
-    // for syncing.
-    fuchsia::modular::AppConfig cloud_provider_config;
-    cloud_provider_config.url = kCloudProviderFirestoreAppUrl;
-    cloud_provider_app_ =
-        std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
-            user_environment_->GetLauncher(), std::move(cloud_provider_config));
-    cloud_provider_app_->services().ConnectToService(
-        cloud_provider_factory_.NewRequest());
+    // If not running in Guest mode, configure the cloud provider for Ledger to
+    // use for syncing.
 
-    cloud_provider = GetCloudProvider(std::move(ledger_token_manager));
+    if (options_.use_cloud_provider_from_environment) {
+      startup_context_->ConnectToEnvironmentService(
+          cloud_provider.NewRequest());
+    } else {
+      cloud_provider = LaunchCloudProvider(std::move(ledger_token_manager));
+    }
+
     ledger_user_id = account_->profile_id;
-
-    // TODO(mesch): Teardown cloud_provider_app_ ?
   }
 
   ledger_repository_factory_.set_error_handler([this](zx_status_t status) {
@@ -878,10 +875,20 @@
       story_id, std::move(entity_provider_request));
 }
 
-fuchsia::ledger::cloud::CloudProviderPtr SessionmgrImpl::GetCloudProvider(
+fuchsia::ledger::cloud::CloudProviderPtr SessionmgrImpl::LaunchCloudProvider(
     fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager) {
   FXL_CHECK(ledger_token_manager);
 
+  fuchsia::modular::AppConfig cloud_provider_app_config;
+  cloud_provider_app_config.url = kCloudProviderFirestoreAppUrl;
+  cloud_provider_app_ =
+      std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
+          user_environment_->GetLauncher(),
+          std::move(cloud_provider_app_config));
+  cloud_provider_app_->services().ConnectToService(
+      cloud_provider_factory_.NewRequest());
+  // TODO(mesch): Teardown cloud_provider_app_ ?
+
   fuchsia::ledger::cloud::CloudProviderPtr cloud_provider;
   auto cloud_provider_config = GetLedgerFirestoreConfig();
 
diff --git a/peridot/bin/sessionmgr/sessionmgr_impl.h b/peridot/bin/sessionmgr/sessionmgr_impl.h
index 19cc922..2946be1 100644
--- a/peridot/bin/sessionmgr/sessionmgr_impl.h
+++ b/peridot/bin/sessionmgr/sessionmgr_impl.h
@@ -68,8 +68,13 @@
     // /data/LEDGER.
     bool use_memfs_for_ledger;
 
-    // If set, DO NOT pass a cloud provider to the ledger.
+    // If set, no cloud provider is configured for Ledger. This overrides any
+    // value of |use_cloud_provider_from_environment|.
     bool no_cloud_provider_for_ledger;
+    // If set, use the cloud provider available in the incoming namespace,
+    // rather than initializing an instance within sessionmgr. This can be used
+    // by Voila to inject a custom cloud provider.
+    bool use_cloud_provider_from_environment;
 
     // Sessionmgr passes args startup agents and session agent to maxwell.
     std::vector<std::string> startup_agents;
@@ -173,7 +178,7 @@
       fuchsia::modular::AppConfig config);
   fuchsia::sys::ServiceProviderPtr GetServiceProvider(const std::string& url);
 
-  fuchsia::ledger::cloud::CloudProviderPtr GetCloudProvider(
+  fuchsia::ledger::cloud::CloudProviderPtr LaunchCloudProvider(
       fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager);
 
   // Called during initialization. Schedules the given action to be executed
@@ -308,7 +313,7 @@
   // Part of Initialize() that is deferred until the first environment service
   // request is received from the session shell, in order to accelerate the
   // startup of session shell.
-  fit::function<void()> finish_initialization_{[]{}};
+  fit::function<void()> finish_initialization_{[] {}};
 
   // Set to |true| when sessionmgr starts its terminating sequence;  this flag
   // can be used to determine whether to reject vending FIDL services.