[element_manager] Allow using Realm from parent

This CL changes the semantics of the `element_manager`
component to use the `fuchsia.component.Realm` protocol
from parent instead of from framework. This is done in order
to enable product variability of the capabilities routed to
the elements collection. Furthermore, the name of the collection
itself is now configurable using structured configuration.

In order to aid a soft transition, a component with the old
semantics and name will be kept until downstream users are moved
to using the new component.

Bug: 95841
Bug: 100933
Change-Id: I7ce6da279058475b8afc84b4929a3cba2eaf4670
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/691451
Reviewed-by: John Shamoon <johnshamoon@google.com>
Reviewed-by: Yegor Pomortsev <ypomortsev@google.com>
Commit-Queue: Yaneury Fermin <yaneury@google.com>
diff --git a/sdk/cts/build/allowed_cts_deps.gni b/sdk/cts/build/allowed_cts_deps.gni
index dd22ef5..5a84743 100644
--- a/sdk/cts/build/allowed_cts_deps.gni
+++ b/sdk/cts/build/allowed_cts_deps.gni
@@ -16,6 +16,7 @@
   # TODO(77889): Determine if this can be in the CTS.
   "//zircon/system/public:public",
   "//src/session/bin/element_manager:element_manager_comp",
+  "//src/session/bin/element_manager:sc_values",
 ]
 
 # Individual Rust dependencies that correspond to an SDK element.
diff --git a/sdk/cts/tests/fidl/fuchsia.element/BUILD.gn b/sdk/cts/tests/fidl/fuchsia.element/BUILD.gn
index f0170bc..8233896 100644
--- a/sdk/cts/tests/fidl/fuchsia.element/BUILD.gn
+++ b/sdk/cts/tests/fidl/fuchsia.element/BUILD.gn
@@ -43,6 +43,7 @@
     ":reference-scenic",
     ":reference-session",
     "//src/session/bin/element_manager:element_manager_comp",
+    "//src/session/bin/element_manager:sc_values",
   ]
 }
 
diff --git a/src/session/bin/element_manager/BUILD.gn b/src/session/bin/element_manager/BUILD.gn
index 00520c9..e7849d8 100644
--- a/src/session/bin/element_manager/BUILD.gn
+++ b/src/session/bin/element_manager/BUILD.gn
@@ -11,6 +11,7 @@
   edition = "2021"
 
   deps = [
+    ":element_config",
     "//sdk/fidl/fuchsia.component:fuchsia.component-rustc",
     "//sdk/fidl/fuchsia.data:fuchsia.data-rustc",
     "//sdk/fidl/fuchsia.element:fuchsia.element-rustc",
@@ -21,6 +22,7 @@
     "//sdk/fidl/fuchsia.ui.app:fuchsia.ui.app-rustc",
     "//sdk/fidl/fuchsia.ui.scenic:fuchsia.ui.scenic-rustc",
     "//src/lib/async-utils",
+    "//src/lib/diagnostics/inspect/rust",
     "//src/lib/fdio/rust:fdio",
     "//src/lib/fidl/rust/fidl",
     "//src/lib/fuchsia",
@@ -54,14 +56,64 @@
   ]
 }
 
-fuchsia_component("element_manager_comp") {
+fuchsia_component_manifest("base_manifest") {
+  manifest = "meta/base.shard.cml"
+}
+
+fuchsia_structured_config_rust_lib("element_config") {
+  cm_label = ":base_manifest"
+}
+
+# The Element Manager component is undergoing a breaking change. Previous
+# versions consumed the `fuchsia.component.Realm` protocol from the framework.
+# However, this behavior has been changed to instead consume the protocol
+# from parent, delegating the necessary routing to the session. All clients of
+# the Element Manager component are to move to use this version. In order to
+# facilitate this transition, the deprecated version of the component is kept.
+#
+# TODO(http://fxbug.dev/95841): Remove `meta/base.shard.cml`
+# and deprecated component manifest.
+fuchsia_component_manifest("manifest") {
   component_name = "element_manager"
   manifest = "meta/element_manager.cml"
+}
+
+fuchsia_structured_config_values("sc_values") {
+  cm_label = ":manifest"
+  values = {
+    elements_collection_name = "elements"
+  }
+}
+
+fuchsia_component("element_manager_comp") {
+  cm_label = ":manifest"
+  deps = [ ":element_manager_bin" ]
+}
+
+fuchsia_component_manifest("new_element_manager_manifest") {
+  component_name = "new_element_manager"
+  manifest = "meta/new_element_manager.cml"
+}
+
+fuchsia_structured_config_values("new_element_manager_sc_values") {
+  cm_label = ":new_element_manager_manifest"
+  values = {
+    elements_collection_name = "elements"
+  }
+}
+
+fuchsia_component("new_element_manager_comp") {
+  cm_label = ":new_element_manager_manifest"
   deps = [ ":element_manager_bin" ]
 }
 
 fuchsia_package("element_manager") {
-  deps = [ ":element_manager_comp" ]
+  deps = [
+    ":element_manager_comp",
+    ":new_element_manager_comp",
+    ":new_element_manager_sc_values",
+    ":sc_values",
+  ]
 }
 
 fuchsia_unittest_package("element_manager_tests") {
diff --git a/src/session/bin/element_manager/meta/base.shard.cml b/src/session/bin/element_manager/meta/base.shard.cml
new file mode 100644
index 0000000..a7f31cf
--- /dev/null
+++ b/src/session/bin/element_manager/meta/base.shard.cml
@@ -0,0 +1,36 @@
+// Copyright 2022 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.
+{
+    include: [ "syslog/client.shard.cml" ],
+    program: {
+        runner: "elf",
+        binary: "bin/element_manager",
+    },
+    capabilities: [
+        {
+            protocol: [ "fuchsia.element.Manager" ],
+        },
+    ],
+    use: [
+        {
+            protocol: [
+                "fuchsia.element.GraphicalPresenter",
+                "fuchsia.sys.Launcher",
+                "fuchsia.ui.scenic.Scenic",
+            ],
+        },
+    ],
+    expose: [
+        {
+            protocol: [ "fuchsia.element.Manager" ],
+            from: "self",
+        },
+    ],
+    config: {
+        elements_collection_name: {
+            type: "string",
+            max_size: 512,
+        },
+    },
+}
diff --git a/src/session/bin/element_manager/meta/element_manager.cml b/src/session/bin/element_manager/meta/element_manager.cml
index 21b5532..62b4931 100644
--- a/src/session/bin/element_manager/meta/element_manager.cml
+++ b/src/session/bin/element_manager/meta/element_manager.cml
@@ -2,34 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 {
-    include: [ "syslog/client.shard.cml" ],
-    program: {
-        runner: "elf",
-        binary: "bin/element_manager",
-    },
+    include: [ "//src/session/bin/element_manager/meta/base.shard.cml" ],
     collections: [
         {
             name: "elements",
             durability: "transient",
         },
     ],
-    capabilities: [
-        {
-            protocol: [ "fuchsia.element.Manager" ],
-        },
-    ],
     use: [
         {
             protocol: "fuchsia.component.Realm",
             from: "framework",
         },
-        {
-            protocol: [
-                "fuchsia.element.GraphicalPresenter",
-                "fuchsia.sys.Launcher",
-                "fuchsia.ui.scenic.Scenic",
-            ],
-        },
     ],
     offer: [
         {
@@ -47,10 +31,4 @@
             to: "#elements",
         },
     ],
-    expose: [
-        {
-            protocol: [ "fuchsia.element.Manager" ],
-            from: "self",
-        },
-    ],
 }
diff --git a/src/session/bin/element_manager/meta/new_element_manager.cml b/src/session/bin/element_manager/meta/new_element_manager.cml
new file mode 100644
index 0000000..44eb64bd
--- /dev/null
+++ b/src/session/bin/element_manager/meta/new_element_manager.cml
@@ -0,0 +1,12 @@
+// Copyright 2022 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.
+{
+    include: [ "//src/session/bin/element_manager/meta/base.shard.cml" ],
+    use: [
+        {
+            protocol: "fuchsia.component.Realm",
+            from: "parent",
+        },
+    ],
+}
diff --git a/src/session/bin/element_manager/src/main.rs b/src/session/bin/element_manager/src/main.rs
index 9385760..d640221 100644
--- a/src/session/bin/element_manager/src/main.rs
+++ b/src/session/bin/element_manager/src/main.rs
@@ -19,6 +19,7 @@
 use {
     crate::element_manager::ElementManager,
     anyhow::Error,
+    element_config::Config,
     fidl_connector::ServiceReconnector,
     fidl_fuchsia_component as fcomponent, fidl_fuchsia_element as felement,
     fidl_fuchsia_sys as fsys,
@@ -26,6 +27,7 @@
     fuchsia_component::{client::connect_to_protocol, server::ServiceFs},
     futures::StreamExt,
     std::rc::Rc,
+    tracing::info,
 };
 
 /// This enum allows the session to match on incoming messages.
@@ -33,17 +35,21 @@
     Manager(felement::ManagerRequestStream),
 }
 
-/// The child collection to add elements to. This must match a collection name declared in
-/// element_manager's CML file.
-const ELEMENT_COLLECTION_NAME: &str = "elements";
-
 /// The maximum number of concurrent requests.
 const NUM_CONCURRENT_REQUESTS: usize = 5;
 
 #[fuchsia::main]
 async fn main() -> Result<(), Error> {
+    info!("Starting.");
+    let config = Config::take_from_startup_handle();
+    let inspector = fuchsia_inspect::component::inspector();
+    inspector.root().record_child("config", |config_node| config.record_inspect(config_node));
+
+    info!("Element collection name set to \"#{}\"", config.elements_collection_name);
+
     let realm = connect_to_protocol::<fcomponent::RealmMarker>()
         .expect("Failed to connect to Realm service");
+
     let sys_launcher = connect_to_protocol::<fsys::LauncherMarker>()
         .expect("Failed to connect to fuchsia.sys.Launcher service");
     let graphical_presenter =
@@ -60,7 +66,7 @@
         realm,
         Some(graphical_presenter),
         sys_launcher,
-        ELEMENT_COLLECTION_NAME,
+        config.elements_collection_name.as_str(),
         scenic_uses_flatland,
     ));
 
@@ -87,7 +93,6 @@
 #[cfg(test)]
 mod tests {
     use {
-        super::ELEMENT_COLLECTION_NAME,
         crate::element_manager::ElementManager,
         fidl::endpoints::{create_proxy_and_stream, spawn_stream_handler},
         fidl::endpoints::{ProtocolMarker, Proxy},
@@ -99,6 +104,8 @@
         test_util::Counter,
     };
 
+    const ELEMENT_COLLECTION_NAME: &str = "elements";
+
     /// Spawns a local `Manager` server.
     ///
     /// # Parameters