[modular] Give sessions a device-local unique identifier.

- For now it takes the value of the account ID, such that re-authentication is
not required for existing users.

- The ID is not explicitly stored anywhere, the uniqueness is guaranteed
by the fact that we can only have one session running at a time. Even if
we had multiple sessions, the uniqueness is guaranteed by the account
ID uniqueness from DB.

- Also renamed some variables in sessionmgr_impl

Change-Id: I73f150ddc874a49ffe9975c2f2fe16f1d8a5732c
diff --git a/peridot/bin/basemgr/session_context_impl.cc b/peridot/bin/basemgr/session_context_impl.cc
index c91fdae..3b07b1d 100644
--- a/peridot/bin/basemgr/session_context_impl.cc
+++ b/peridot/bin/basemgr/session_context_impl.cc
@@ -16,7 +16,7 @@
 namespace modular {
 
 SessionContextImpl::SessionContextImpl(
-    fuchsia::sys::Launcher* const launcher,
+    fuchsia::sys::Launcher* const launcher, std::string session_id,
     fuchsia::modular::AppConfig sessionmgr_config,
     fuchsia::modular::AppConfig session_shell_config,
     fuchsia::modular::AppConfig story_shell_config,
@@ -34,19 +34,10 @@
   FXL_CHECK(get_presentation_);
   FXL_CHECK(on_session_shutdown_);
 
+  // TODO(MF-280): We should replace USER* with SESSION* below. However, this
+  // will force users to re-authenticate, so the timing needs to be considered.
   // 0. Generate the path to map '/data' for the sessionmgr we are starting.
-  std::string data_origin;
-  if (!account) {
-    // Guest user.
-    // Generate a random number to be used in this case.
-    uint32_t random_number = 0;
-    zx_cprng_draw(&random_number, sizeof random_number);
-    data_origin = std::string("/data/modular/USER_GUEST_") +
-                  std::to_string(random_number);
-  } else {
-    // Non-guest user.
-    data_origin = std::string("/data/modular/USER_") + std::string(account->id);
-  }
+  std::string data_origin = std::string("/data/modular/USER_") + session_id;
 
   FXL_LOG(INFO) << "SESSIONMGR DATA ORIGIN IS " << data_origin;
 
@@ -57,7 +48,7 @@
   // 2. Initialize the Sessionmgr service.
   sessionmgr_app_->services().ConnectToService(sessionmgr_.NewRequest());
   sessionmgr_->Initialize(
-      std::move(account), std::move(session_shell_config),
+      session_id, std::move(account), std::move(session_shell_config),
       std::move(story_shell_config), use_session_shell_for_story_shell_factory,
       std::move(ledger_token_manager), std::move(agent_token_manager),
       session_context_binding_.NewBinding(), std::move(view_owner_request));
diff --git a/peridot/bin/basemgr/session_context_impl.h b/peridot/bin/basemgr/session_context_impl.h
index 1016ee6..ed1907a 100644
--- a/peridot/bin/basemgr/session_context_impl.h
+++ b/peridot/bin/basemgr/session_context_impl.h
@@ -34,8 +34,8 @@
 class SessionContextImpl : fuchsia::modular::internal::SessionContext {
  public:
   // Called after perfoming shutdown of the session, to signal our completion
-  // (and deletion of our instance) to our owner, we do it using a callback
-  // supplied to us in our constructor. (The alternative is to take in a
+  // (and deletion of our instance) to our owner, this is done using a callback
+  // supplied in the constructor. (The alternative is to take in a
   // SessionProvider*, which seems a little specific and overscoped).
   using OnSessionShutdownCallback = fit::function<void(bool logout_users)>;
 
@@ -43,8 +43,12 @@
   using GetPresentationCallback = fit::function<void(
       fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request)>;
 
+  // |session_id| is the device-local unique identifier for this session. Caller
+  // must ensure its uniqueness. sessionmgr creates an Environment namespace
+  // with the given |session_id|, and this will crash if it tries to create an
+  // environment with a pre-existing name.
   SessionContextImpl(
-      fuchsia::sys::Launcher* const launcher,
+      fuchsia::sys::Launcher* const launcher, std::string session_id,
       fuchsia::modular::AppConfig sessionmgr_config,
       fuchsia::modular::AppConfig session_shell_config,
       fuchsia::modular::AppConfig story_shell_config,
diff --git a/peridot/bin/basemgr/session_context_impl_unittest.cc b/peridot/bin/basemgr/session_context_impl_unittest.cc
index 22e22c2..8b72816 100644
--- a/peridot/bin/basemgr/session_context_impl_unittest.cc
+++ b/peridot/bin/basemgr/session_context_impl_unittest.cc
@@ -17,6 +17,9 @@
 using ::component::testing::FakeLauncher;
 using SessionContextImplTest = gtest::TestLoopFixture;
 
+// Unique identifier for a test session.
+constexpr char kSessionId[] = "session_id";
+
 TEST_F(SessionContextImplTest, StartSessionmgrWithTokenManagers) {
   FakeLauncher launcher;
   std::string url = "test_url_string";
@@ -35,7 +38,7 @@
   fuchsia::auth::TokenManagerPtr agent_token_manager;
 
   SessionContextImpl impl(
-      &launcher, CloneStruct(app_config) /* sessionmgr_config */,
+      &launcher, kSessionId, CloneStruct(app_config) /* sessionmgr_config */,
       CloneStruct(app_config) /* session_shell_config */,
       CloneStruct(app_config) /* story_shell_config */,
       false, /* use_session_shell_for_story_shell_factory */
@@ -68,7 +71,7 @@
 
   bool done_callback_called = false;
   SessionContextImpl impl(
-      &launcher, /* sessionmgr_config= */ CloneStruct(app_config),
+      &launcher, kSessionId, /* sessionmgr_config= */ CloneStruct(app_config),
       /* session_shell_config= */ CloneStruct(app_config),
       /* story_shell_config= */ CloneStruct(app_config),
       /* use_session_shell_for_story_shell_factory= */ false,
diff --git a/peridot/bin/basemgr/session_provider.cc b/peridot/bin/basemgr/session_provider.cc
index 64bee60..6e050c1 100644
--- a/peridot/bin/basemgr/session_provider.cc
+++ b/peridot/bin/basemgr/session_provider.cc
@@ -50,10 +50,25 @@
     }
   };
 
+  // TODO(MF-280): Currently, session_id maps to account ID. We should generate
+  // unique session ID's and store the mapping of session ID to session once we
+  // support multiple sessions.
+  std::string session_id;
+  if (!account) {
+    // Guest user. Generate a random number to be used in this case.
+    uint32_t random_number = 0;
+    zx_cprng_draw(&random_number, sizeof random_number);
+    session_id = std::to_string(random_number);
+  } else {
+    // Non-guest user.
+    session_id = std::string(account->id);
+  }
+
   // Session context initializes and holds the sessionmgr process.
   session_context_ = std::make_unique<SessionContextImpl>(
-      launcher_, CloneStruct(sessionmgr_), CloneStruct(session_shell_),
-      CloneStruct(story_shell_), use_session_shell_for_story_shell_factory_,
+      launcher_, session_id, CloneStruct(sessionmgr_),
+      CloneStruct(session_shell_), CloneStruct(story_shell_),
+      use_session_shell_for_story_shell_factory_,
       std::move(ledger_token_manager), std::move(agent_token_manager),
       std::move(account), std::move(view_owner),
       /* get_presentation= */
diff --git a/peridot/bin/sessionmgr/sessionmgr_impl.cc b/peridot/bin/sessionmgr/sessionmgr_impl.cc
index 1169f16..a29f38c 100644
--- a/peridot/bin/sessionmgr/sessionmgr_impl.cc
+++ b/peridot/bin/sessionmgr/sessionmgr_impl.cc
@@ -65,7 +65,7 @@
 constexpr char kModuleResolverUrl[] =
     "fuchsia-pkg://fuchsia.com/module_resolver#meta/module_resolver.cmx";
 
-constexpr char kUserEnvironmentLabelPrefix[] = "user-";
+constexpr char kSessionEnvironmentLabelPrefix[] = "session-";
 
 constexpr char kMessageQueuePath[] = "/data/MESSAGE_QUEUES/v1/";
 
@@ -90,10 +90,6 @@
   return config;
 }
 
-std::string GetAccountId(const fuchsia::modular::auth::AccountPtr& account) {
-  return !account ? "GUEST" : account->id;
-}
-
 // Creates a function that can be used as termination action passed to AtEnd(),
 // which when called invokes the reset() method on the object pointed to by the
 // argument. Used to reset() fidl pointers and std::unique_ptr<>s fields.
@@ -186,7 +182,7 @@
 SessionmgrImpl::~SessionmgrImpl() = default;
 
 void SessionmgrImpl::Initialize(
-    fuchsia::modular::auth::AccountPtr account,
+    std::string session_id, fuchsia::modular::auth::AccountPtr account,
     fuchsia::modular::AppConfig session_shell_config,
     fuchsia::modular::AppConfig story_shell_config,
     bool use_session_shell_for_story_shell_factory,
@@ -227,6 +223,7 @@
   session_context_ = session_context.Bind();
   AtEnd(Reset(&session_context_));
 
+  InitializeSessionEnvironment(session_id);
   InitializeUser(std::move(account), std::move(agent_token_manager));
   InitializeSessionShell(
       std::move(session_shell_config),
@@ -239,6 +236,18 @@
   story_provider_impl_->SetSessionShell(std::move(session_shell));
 }
 
+void SessionmgrImpl::InitializeSessionEnvironment(std::string session_id) {
+  session_id_ = session_id;
+
+  static const auto* const kEnvServices = new std::vector<std::string>{
+      fuchsia::modular::DeviceMap::Name_, fuchsia::modular::Clipboard::Name_};
+  session_environment_ = std::make_unique<Environment>(
+      startup_context_->environment(),
+      std::string(kSessionEnvironmentLabelPrefix) + session_id_, *kEnvServices,
+      /* kill_on_oom = */ true);
+  AtEnd(Reset(&session_environment_));
+}
+
 void SessionmgrImpl::InitializeUser(
     fuchsia::modular::auth::AccountPtr account,
     fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager) {
@@ -247,15 +256,6 @@
 
   account_ = std::move(account);
   AtEnd(Reset(&account_));
-
-  static const auto* const kEnvServices = new std::vector<std::string>{
-      fuchsia::modular::DeviceMap::Name_, fuchsia::modular::Clipboard::Name_};
-  user_environment_ = std::make_unique<Environment>(
-      startup_context_->environment(),
-      std::string(kUserEnvironmentLabelPrefix) + GetAccountId(account_),
-      *kEnvServices,
-      /* kill_on_oom = */ true);
-  AtEnd(Reset(&user_environment_));
 }
 
 zx::channel SessionmgrImpl::GetLedgerRepositoryDirectory() {
@@ -290,7 +290,7 @@
 
   ledger_app_ =
       std::make_unique<AppClient<fuchsia::ledger::internal::LedgerController>>(
-          user_environment_->GetLauncher(), std::move(ledger_config), "",
+          session_environment_->GetLauncher(), std::move(ledger_config), "",
           nullptr);
   ledger_app_->SetAppErrorHandler([this] {
     FXL_LOG(ERROR) << "Ledger seems to have crashed unexpectedly." << std::endl
@@ -355,19 +355,19 @@
 
 void SessionmgrImpl::InitializeDeviceMap() {
   // fuchsia::modular::DeviceMap service
-  const std::string device_id = LoadDeviceID(GetAccountId(account_));
-  device_name_ = LoadDeviceName(GetAccountId(account_));
+  const std::string device_id = LoadDeviceID(session_id_);
+  device_name_ = LoadDeviceName(session_id_);
   const std::string device_profile = LoadDeviceProfile();
 
   device_map_impl_ = std::make_unique<DeviceMapImpl>(
       device_name_, device_id, device_profile, ledger_client_.get(),
       fuchsia::ledger::PageId());
-  user_environment_->AddService<fuchsia::modular::DeviceMap>(
+  session_environment_->AddService<fuchsia::modular::DeviceMap>(
       [this](fidl::InterfaceRequest<fuchsia::modular::DeviceMap> request) {
         if (terminating_) {
           return;
         }
-        // device_map_impl_ may be reset before user_environment_.
+        // device_map_impl_ may be reset before session_environment_.
         if (device_map_impl_) {
           device_map_impl_->Connect(std::move(request));
         }
@@ -379,7 +379,7 @@
   agent_runner_->ConnectToAgent(kAppId, kClipboardAgentUrl,
                                 services_from_clipboard_agent_.NewRequest(),
                                 clipboard_agent_controller_.NewRequest());
-  user_environment_->AddService<fuchsia::modular::Clipboard>(
+  session_environment_->AddService<fuchsia::modular::Clipboard>(
       [this](fidl::InterfaceRequest<fuchsia::modular::Clipboard> request) {
         if (terminating_) {
           return;
@@ -391,7 +391,7 @@
 
 void SessionmgrImpl::InitializeMessageQueueManager() {
   std::string message_queue_path = kMessageQueuePath;
-  message_queue_path.append(GetAccountId(account_));
+  message_queue_path.append(session_id_);
   if (!files::CreateDirectory(message_queue_path)) {
     FXL_LOG(FATAL) << "Failed to create message queue directory: "
                    << message_queue_path;
@@ -475,7 +475,7 @@
   AtEnd(Reset(&agent_runner_storage_));
 
   agent_runner_.reset(new AgentRunner(
-      user_environment_->GetLauncher(), message_queue_manager_.get(),
+      session_environment_->GetLauncher(), message_queue_manager_.get(),
       ledger_repository_.get(), agent_runner_storage_.get(),
       agent_token_manager_.get(), user_intelligence_provider_impl_.get(),
       entity_provider_runner_.get()));
@@ -510,8 +510,9 @@
 
     context_engine_app_ =
         std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
-            user_environment_->GetLauncher(), std::move(context_engine_config),
-            "" /* data_origin */, std::move(service_list));
+            session_environment_->GetLauncher(),
+            std::move(context_engine_config), "" /* data_origin */,
+            std::move(service_list));
     context_engine_app_->services().ConnectToService(
         std::move(context_engine_request));
     AtEnd(Reset(&context_engine_app_));
@@ -568,8 +569,9 @@
     // isolate the data it reads to a subdir of /data and map that in here.
     module_resolver_app_ =
         std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
-            user_environment_->GetLauncher(), std::move(module_resolver_config),
-            "" /* data_origin */, std::move(service_list));
+            session_environment_->GetLauncher(),
+            std::move(module_resolver_config), "" /* data_origin */,
+            std::move(service_list));
     AtEnd(Reset(&module_resolver_app_));
     AtEnd(Teardown(kBasicTimeout, "Resolver", module_resolver_app_.get()));
   }
@@ -617,7 +619,7 @@
       startup_context_->ConnectToEnvironmentService<fuchsia::sys::Loader>()));
 
   story_provider_impl_.reset(new StoryProviderImpl(
-      user_environment_.get(), device_map_impl_->current_device_id(),
+      session_environment_.get(), device_map_impl_->current_device_id(),
       session_storage_.get(), std::move(story_shell_config),
       std::move(story_shell_factory_ptr), component_context_info,
       std::move(focus_provider_story_provider),
@@ -773,7 +775,7 @@
   }
 
   session_shell_app_ = std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
-      user_environment_->GetLauncher(), std::move(session_shell_config),
+      session_environment_->GetLauncher(), std::move(session_shell_config),
       /* data_origin = */ "", std::move(service_list));
 
   session_shell_app_->SetAppErrorHandler([this] {
@@ -942,7 +944,7 @@
   cloud_provider_app_config.url = kCloudProviderFirestoreAppUrl;
   cloud_provider_app_ =
       std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
-          user_environment_->GetLauncher(),
+          session_environment_->GetLauncher(),
           std::move(cloud_provider_app_config));
   cloud_provider_app_->services().ConnectToService(
       cloud_provider_factory_.NewRequest());
diff --git a/peridot/bin/sessionmgr/sessionmgr_impl.h b/peridot/bin/sessionmgr/sessionmgr_impl.h
index d2af28c..876fa57 100644
--- a/peridot/bin/sessionmgr/sessionmgr_impl.h
+++ b/peridot/bin/sessionmgr/sessionmgr_impl.h
@@ -69,7 +69,7 @@
  private:
   // |Sessionmgr|
   void Initialize(
-      fuchsia::modular::auth::AccountPtr account,
+      std::string session_id, fuchsia::modular::auth::AccountPtr account,
       fuchsia::modular::AppConfig session_shell_config,
       fuchsia::modular::AppConfig story_shell_config,
       bool use_session_shell_for_story_shell_factory,
@@ -85,6 +85,9 @@
                         SwapSessionShellCallback callback) override;
 
   // Sequence of Initialize() broken up into steps for clarity.
+  // TODO(MF-279): Remove |account| and |agent_token_manager| once sessions
+  // start receiving persona handles.
+  void InitializeSessionEnvironment(std::string session_id);
   void InitializeUser(
       fuchsia::modular::auth::AccountPtr account,
       fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager);
@@ -188,6 +191,10 @@
 
   void ConnectSessionShellToStoryProvider();
 
+  // The device-local unique identifier for this session. The uniqueness
+  // is enforced by basemgr which vends sessions.
+  std::string session_id_;
+
   component::StartupContext* const startup_context_;
   fuchsia::modular::internal::SessionmgrConfigPtr config_;
   std::unique_ptr<scoped_tmpfs::ScopedTmpFS> memfs_for_ledger_;
@@ -211,7 +218,7 @@
   // Provides services to the Ledger
   component::ServiceProviderImpl ledger_service_provider_;
 
-  std::unique_ptr<Environment> user_environment_;
+  std::unique_ptr<Environment> session_environment_;
 
   fuchsia::modular::auth::AccountPtr account_;
 
diff --git a/peridot/bin/voila/src/main.rs b/peridot/bin/voila/src/main.rs
index f95ae35..853421b 100644
--- a/peridot/bin/voila/src/main.rs
+++ b/peridot/bin/voila/src/main.rs
@@ -150,6 +150,7 @@
 
         sessionmgr
             .initialize(
+                "session_id", /* session_id */
                 Some(OutOfLine(&mut account)),
                 &mut session_shell_config,
                 &mut story_shell_config,
diff --git a/sdk/fidl/fuchsia.modular.internal/sessionmgr.fidl b/sdk/fidl/fuchsia.modular.internal/sessionmgr.fidl
index 0a2fcee..85ae8a6 100644
--- a/sdk/fidl/fuchsia.modular.internal/sessionmgr.fidl
+++ b/sdk/fidl/fuchsia.modular.internal/sessionmgr.fidl
@@ -11,15 +11,20 @@
 using fuchsia.ui.viewsv1token;
 
 // The basemgr application (there is no |Basemgr| service) requests
-// an instance of this service in order to launch and display a |Sessionmgr| per
-// user.
-// TODO(alexmin): Re-word this bit once the Sessionmgr implementation is landed.
+// an instance of this service in order to launch and display a |Sessionmgr|.
 [Discoverable] // Created by sessionmgr application.
 protocol Sessionmgr {
-    // Launches a sessionmgr instance for a user identified by |user_id| and
-    // specific TokenManager handles for ledger and agent_runner.
-    // TODO(alhaad): Fold paramters into |UserContext|.
-    Initialize(fuchsia.modular.auth.Account? account,
+    // Launches a sessionmgr instance identified by a unique device-local
+    // |session_id|. The uniqueness of |session_id| must be guaranteed by the
+    // caller, because |sessionmgr| creates an Environment namespace with the
+    // given |session_id|, and this will crash if we try to create an
+    // environment with a pre-existing name, because the services sessionmgr
+    // tries to access won't be available.
+    //
+    // TODO(MF-287): Address issues around client-generated session_id and
+    // initialization pattern of sessionmgr.
+    Initialize(string session_id,
+               fuchsia.modular.auth.Account? account,
                fuchsia.modular.AppConfig session_shell,
                fuchsia.modular.AppConfig story_shell,
                bool use_session_shell_for_story_shell_factory,