[appmgr] Pass services through to sys realm properly

Several services from appmgr's own environment (provided by
non-component processes like devcoordinator) were recently added to the
list in namespace.cc improperly, which made them available in all appmgr
realms. These services are privileged and should be made available only
as necessary.

This change adds a list of services for appmgr to pass through from /svc
in its own namespace (i.e. the /svc hosted by svchost) to the root 'app'
realm, and then makes a further change in sysmgr to inherit these
services into the 'sys' realm. If any of these services are needed in
nested realms under sys, they should be routed normally as is done for
any other realm or environment.

Also updates lots of test components that depend on
fuchsia.scheduler.ProfileProvider to explicitly include this service
from the sys realm in their hermetic test environment.

CF-769 #done

Change-Id: I49114041fe05425979d75bc7fcefa22826b2632c
diff --git a/garnet/bin/appmgr/BUILD.gn b/garnet/bin/appmgr/BUILD.gn
index 04111a2..77028ab 100644
--- a/garnet/bin/appmgr/BUILD.gn
+++ b/garnet/bin/appmgr/BUILD.gn
@@ -62,8 +62,6 @@
     "//third_party/rapidjson",
     "//zircon/public/fidl/fuchsia-inspect",
     "//zircon/public/fidl/fuchsia-process",
-    "//zircon/public/fidl/fuchsia-scheduler",
-    "//zircon/public/fidl/fuchsia-virtualconsole",
     "//zircon/public/lib/async-loop-cpp",
     "//zircon/public/lib/fit",
     "//zircon/public/lib/fs",
@@ -73,11 +71,6 @@
     "//zircon/public/lib/zx",
   ]
 
-  deps = [
-    "//zircon/public/fidl/fuchsia-device-manager",
-    "//zircon/public/fidl/fuchsia-kernel",
-  ]
-
   defines = [ "_ALL_SOURCE=1" ]
 }
 
@@ -112,6 +105,10 @@
   deps = [
     ":lib",
     "//sdk/lib/sys/cpp",
+    "//zircon/public/fidl/fuchsia-device-manager",
+    "//zircon/public/fidl/fuchsia-kernel",
+    "//zircon/public/fidl/fuchsia-scheduler",
+    "//zircon/public/fidl/fuchsia-virtualconsole",
   ]
 
   # appmgr starts early in the boot sequence before shared libraries from
diff --git a/garnet/bin/appmgr/appmgr.cc b/garnet/bin/appmgr/appmgr.cc
index 07dcaa9..e97f2aa 100644
--- a/garnet/bin/appmgr/appmgr.cc
+++ b/garnet/bin/appmgr/appmgr.cc
@@ -28,13 +28,13 @@
       storage_watchdog_(StorageWatchdog("/data", "/data/cache")) {
   // 0. Start storage watchdog for cache storage
   storage_watchdog_.Run(dispatcher);
+
   // 1. Create root realm.
-  RealmArgs realm_args = RealmArgs::Make(
-      nullptr, kRootLabel, "/data", "/data/cache", args.environment_services,
-      args.run_virtual_console, fuchsia::sys::EnvironmentOptions{});
-
+  RealmArgs realm_args = RealmArgs::MakeWithAdditionalServices(
+      nullptr, kRootLabel, "/data", "/data/cache",
+      std::move(args.environment_services), args.run_virtual_console,
+      std::move(args.root_realm_services), fuchsia::sys::EnvironmentOptions{});
   root_realm_ = Realm::Create(std::move(realm_args));
-
   FXL_CHECK(root_realm_) << "Cannot create root realm ";
 
   // 2. Publish outgoing directories.
diff --git a/garnet/bin/appmgr/appmgr.h b/garnet/bin/appmgr/appmgr.h
index 454d236..5a02be9 100644
--- a/garnet/bin/appmgr/appmgr.h
+++ b/garnet/bin/appmgr/appmgr.h
@@ -20,6 +20,7 @@
 
 struct AppmgrArgs {
   zx_handle_t pa_directory_request;
+  fuchsia::sys::ServiceListPtr root_realm_services;
   const std::shared_ptr<sys::ServiceDirectory> environment_services;
   std::string sysmgr_url;
   fidl::VectorPtr<std::string> sysmgr_args;
diff --git a/garnet/bin/appmgr/component_controller_unittest.cc b/garnet/bin/appmgr/component_controller_unittest.cc
index 2d61505..dc6dc3d 100644
--- a/garnet/bin/appmgr/component_controller_unittest.cc
+++ b/garnet/bin/appmgr/component_controller_unittest.cc
@@ -6,10 +6,6 @@
 #include <fs/pseudo-file.h>
 #include <fs/remote-dir.h>
 #include <fs/synchronous-vfs.h>
-#include <fuchsia/device/manager/cpp/fidl.h>
-#include <fuchsia/kernel/cpp/fidl.h>
-#include <fuchsia/scheduler/cpp/fidl.h>
-#include <fuchsia/virtualconsole/cpp/fidl.h>
 #include <lib/fdio/spawn.h>
 #include <zircon/syscalls/object.h>
 
@@ -68,14 +64,9 @@
   return std::vector<std::string>{
       ".",
       Namespace::Launcher::Name_,
-      fuchsia::device::manager::Administrator::Name_,
-      fuchsia::device::manager::DebugDumper::Name_,
-      fuchsia::kernel::DebugBroker::Name_,
       fuchsia::process::Launcher::Name_,
       fuchsia::process::Resolver::Name_,
-      fuchsia::scheduler::ProfileProvider::Name_,
       fuchsia::sys::Environment::Name_,
-      fuchsia::virtualconsole::SessionManager::Name_,
       fuchsia::sys::test::CacheControl::Name_,
   };
 }
diff --git a/garnet/bin/appmgr/main.cc b/garnet/bin/appmgr/main.cc
index cd110de..6f3280f 100644
--- a/garnet/bin/appmgr/main.cc
+++ b/garnet/bin/appmgr/main.cc
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <fuchsia/device/manager/cpp/fidl.h>
+#include <fuchsia/kernel/cpp/fidl.h>
+#include <fuchsia/scheduler/cpp/fidl.h>
+#include <fuchsia/virtualconsole/cpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/sys/cpp/service_directory.h>
 #include <trace-provider/provider.h>
@@ -11,17 +15,41 @@
 #include "garnet/bin/appmgr/appmgr.h"
 #include "src/lib/fxl/command_line.h"
 
+namespace {
+
+std::vector<std::string> RootRealmServices() {
+  return std::vector<std::string>{
+      fuchsia::device::manager::Administrator::Name_,
+      fuchsia::device::manager::DebugDumper::Name_,
+      fuchsia::kernel::DebugBroker::Name_,
+      fuchsia::scheduler::ProfileProvider::Name_,
+      fuchsia::virtualconsole::SessionManager::Name_,
+  };
+}
+
+}  // namespace
+
 int main(int argc, char** argv) {
   async::Loop loop(&kAsyncLoopConfigAttachToThread);
   auto request = zx_take_startup_handle(PA_DIRECTORY_REQUEST);
 
   auto environment_services = sys::ServiceDirectory::CreateFromNamespace();
 
+  // Certain services in appmgr's /svc, which is served by svchost, are added to
+  // the root realm so they can be routed into a nested environment (such as the
+  // sys realm in sysmgr) and used in components.
+  fuchsia::sys::ServiceListPtr root_realm_services(
+      new fuchsia::sys::ServiceList);
+  root_realm_services->names = RootRealmServices();
+  root_realm_services->host_directory =
+      environment_services->CloneChannel().TakeChannel();
+
   trace::TraceProviderWithFdio trace_provider(loop.dispatcher());
 
   component::AppmgrArgs args{
       .pa_directory_request = std::move(request),
-      .environment_services = environment_services,
+      .root_realm_services = std::move(root_realm_services),
+      .environment_services = std::move(environment_services),
       .sysmgr_url = "fuchsia-pkg://fuchsia.com/sysmgr#meta/sysmgr.cmx",
       .sysmgr_args = {},
       .run_virtual_console = true,
diff --git a/garnet/bin/appmgr/namespace.cc b/garnet/bin/appmgr/namespace.cc
index 5ecdbaf..e54abd5 100644
--- a/garnet/bin/appmgr/namespace.cc
+++ b/garnet/bin/appmgr/namespace.cc
@@ -4,11 +4,7 @@
 
 #include "garnet/bin/appmgr/namespace.h"
 
-#include <fuchsia/device/manager/cpp/fidl.h>
-#include <fuchsia/kernel/cpp/fidl.h>
 #include <fuchsia/process/cpp/fidl.h>
-#include <fuchsia/scheduler/cpp/fidl.h>
-#include <fuchsia/virtualconsole/cpp/fidl.h>
 #include <lib/async/default.h>
 #include <lib/fdio/directory.h>
 #include <lib/fdio/fd.h>
@@ -19,8 +15,8 @@
 
 #include "garnet/bin/appmgr/job_provider_impl.h"
 #include "garnet/bin/appmgr/realm.h"
-#include "garnet/bin/appmgr/util.h"
 #include "garnet/bin/appmgr/storage_watchdog.h"
+#include "garnet/bin/appmgr/util.h"
 
 namespace component {
 
@@ -31,6 +27,9 @@
       services_(fbl::AdoptRef(new ServiceProviderDirImpl(service_whitelist))),
       job_provider_(fbl::AdoptRef(new JobProviderImpl(realm))),
       realm_(realm) {
+  // WARNING! Do not add new services here! This makes services available in all
+  // component namespaces ambiently without requiring proper routing between
+  // realms, and this list should not be expanded.
   services_->AddService(
       fuchsia::sys::Environment::Name_,
       fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
@@ -62,6 +61,9 @@
                       std::move(channel)));
         return ZX_OK;
       })));
+  // WARNING! Do not add new services here! This makes services available in all
+  // component namespaces ambiently without requiring proper routing between
+  // realms, and this list should not be expanded.
 
   if (additional_services) {
     auto& names = additional_services->names;
@@ -95,46 +97,8 @@
 
   // If any of these services aren't in additional_services or the parent
   // namespace, add them here directly. (AddService skips duplicate services)
-  services_->AddService(
-      fuchsia::scheduler::ProfileProvider::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
-        realm_->environment_services()->Connect(
-            fidl::InterfaceRequest<fuchsia::scheduler::ProfileProvider>(
-                std::move(channel)));
-        return ZX_OK;
-      })));
-  services_->AddService(
-      fuchsia::kernel::DebugBroker::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
-        realm_->environment_services()->Connect(
-            fidl::InterfaceRequest<fuchsia::kernel::DebugBroker>(
-                std::move(channel)));
-        return ZX_OK;
-      })));
-  services_->AddService(
-      fuchsia::device::manager::DebugDumper::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
-        realm_->environment_services()->Connect(
-            fidl::InterfaceRequest<fuchsia::device::manager::DebugDumper>(
-                std::move(channel)));
-        return ZX_OK;
-      })));
-  services_->AddService(
-      fuchsia::device::manager::Administrator::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
-        realm_->environment_services()->Connect(
-            fidl::InterfaceRequest<fuchsia::device::manager::Administrator>(
-                std::move(channel)));
-        return ZX_OK;
-      })));
-  services_->AddService(
-      fuchsia::virtualconsole::SessionManager::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
-        realm_->environment_services()->Connect(
-            fidl::InterfaceRequest<fuchsia::virtualconsole::SessionManager>(
-                std::move(channel)));
-        return ZX_OK;
-      })));
+  // TODO: Add to RootRealmServices in main.cc instead of adding automatically
+  // to all namespaces here.
   services_->AddService(
       CacheControl::Name_,
       fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
diff --git a/garnet/bin/run_test_component/BUILD.gn b/garnet/bin/run_test_component/BUILD.gn
index 29b5c88..ab5208b 100644
--- a/garnet/bin/run_test_component/BUILD.gn
+++ b/garnet/bin/run_test_component/BUILD.gn
@@ -31,6 +31,7 @@
     "//third_party/rapidjson",
     "//zircon/public/fidl/fuchsia-net",
     "//zircon/public/fidl/fuchsia-net-stack",
+    "//zircon/public/fidl/fuchsia-scheduler",
   ]
 }
 
diff --git a/garnet/bin/run_test_component/test_metadata.cc b/garnet/bin/run_test_component/test_metadata.cc
index 23a695d..536efa0 100644
--- a/garnet/bin/run_test_component/test_metadata.cc
+++ b/garnet/bin/run_test_component/test_metadata.cc
@@ -7,6 +7,7 @@
 #include <fuchsia/net/cpp/fidl.h>
 #include <fuchsia/net/stack/cpp/fidl.h>
 #include <fuchsia/netstack/cpp/fidl.h>
+#include <fuchsia/scheduler/cpp/fidl.h>
 
 #include <unordered_set>
 
@@ -22,9 +23,13 @@
 constexpr char kSystemServices[] = "system-services";
 
 const std::unordered_set<std::string> kAllowedSystemServices = {
-    fuchsia::net::Connectivity::Name_,  fuchsia::net::SocketProvider::Name_,
-    fuchsia::net::stack::Stack::Name_,  fuchsia::netstack::Netstack::Name_,
-    fuchsia::ui::scenic::Scenic::Name_, fuchsia::ui::policy::Presenter::Name_};
+    fuchsia::net::Connectivity::Name_,
+    fuchsia::net::SocketProvider::Name_,
+    fuchsia::net::stack::Stack::Name_,
+    fuchsia::netstack::Netstack::Name_,
+    fuchsia::scheduler::ProfileProvider::Name_,
+    fuchsia::ui::scenic::Scenic::Name_,
+    fuchsia::ui::policy::Presenter::Name_};
 }  // namespace
 
 TestMetadata::TestMetadata() {}
diff --git a/garnet/bin/sysmgr/app.cc b/garnet/bin/sysmgr/app.cc
index 60370be..abfa66c 100644
--- a/garnet/bin/sysmgr/app.cc
+++ b/garnet/bin/sysmgr/app.cc
@@ -111,9 +111,14 @@
   service_list->host_directory = OpenAsDirectory();
   fuchsia::sys::EnvironmentPtr environment;
   component_context_->svc()->Connect(environment.NewRequest());
+  // Inherit services from the root appmgr realm, which includes certain
+  // services currently implemented by non-component processes that are passed
+  // through appmgr to this sys realm. Note that |service_list| will override
+  // the inherited services if it includes services also in the root realm.
+  fuchsia::sys::EnvironmentOptions options = {.inherit_parent_services = true};
   environment->CreateNestedEnvironment(
       std::move(env_request), env_controller_.NewRequest(), kDefaultLabel,
-      std::move(service_list), {});
+      std::move(service_list), std::move(options));
 
   // Connect to startup services
   for (auto& startup_service : config.TakeStartupServices()) {
diff --git a/garnet/bin/sysmgr/integration_tests/BUILD.gn b/garnet/bin/sysmgr/integration_tests/BUILD.gn
index 0980508..a278d05 100644
--- a/garnet/bin/sysmgr/integration_tests/BUILD.gn
+++ b/garnet/bin/sysmgr/integration_tests/BUILD.gn
@@ -59,6 +59,7 @@
   deps = [
     ":interface",
     "//garnet/bin/appmgr:appmgr_for_test",
+    "//garnet/examples/fidl/services:echo",
     "//garnet/public/lib/gtest",
     "//sdk/lib/sys/cpp",
     "//src/lib/fxl",
@@ -126,4 +127,7 @@
       dest = "mock_resolver.cmx"
     },
   ]
+
+  components =
+      [ "//garnet/examples/fidl/echo_server_rust:echo_server_rust_component" ]
 }
diff --git a/garnet/bin/sysmgr/integration_tests/meta/service_startup_test.cmx b/garnet/bin/sysmgr/integration_tests/meta/service_startup_test.cmx
index 5c90ec8..10eea9a 100644
--- a/garnet/bin/sysmgr/integration_tests/meta/service_startup_test.cmx
+++ b/garnet/bin/sysmgr/integration_tests/meta/service_startup_test.cmx
@@ -1,10 +1,24 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "injected-services": {
+                "fidl.examples.echo.Echo": "fuchsia-pkg://fuchsia.com/sysmgr_integration_tests#meta/echo_server_rust.cmx"
+            }
+        }
+    },
     "program": {
         "binary": "test/service_startup_test"
     },
     "sandbox": {
-        "services": [ "fuchsia.process.Launcher" ],
-        "pkgfs": [ "packages" ],
-        "system": [ "data/appmgr" ]
+        "pkgfs": [
+            "packages"
+        ],
+        "services": [
+            "fidl.examples.echo.Echo",
+            "fuchsia.process.Launcher"
+        ],
+        "system": [
+            "data/appmgr"
+        ]
     }
 }
diff --git a/garnet/bin/sysmgr/integration_tests/package_updating_loader_test.cc b/garnet/bin/sysmgr/integration_tests/package_updating_loader_test.cc
index 68e7b59..a46f47e 100644
--- a/garnet/bin/sysmgr/integration_tests/package_updating_loader_test.cc
+++ b/garnet/bin/sysmgr/integration_tests/package_updating_loader_test.cc
@@ -31,6 +31,10 @@
 namespace sysmgr {
 namespace {
 
+const char kEchoServerURL[] =
+    "fuchsia-pkg://fuchsia.com/sysmgr_integration_tests#meta/"
+    "echo_server_rust.cmx";
+
 class PackageResolverMock : public fuchsia::pkg::PackageResolver {
  public:
   explicit PackageResolverMock(zx_status_t status) : status_(status) {}
@@ -157,9 +161,7 @@
   // by trying to use a service offered by it.
   zx::channel h1, h2;
   ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
-  auto launch_info = CreateLaunchInfo(
-      "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx",
-      std::move(h2));
+  auto launch_info = CreateLaunchInfo(kEchoServerURL, std::move(h2));
   auto controller = env_->CreateComponent(std::move(launch_info));
   fidl::examples::echo::EchoPtr echo;
   ConnectToServiceAt(std::move(h1), echo.NewRequest());
@@ -171,7 +173,8 @@
   // Verify that Resolve was called with the expected arguments.
   fuchsia::pkg::UpdatePolicy policy;
   policy.fetch_if_absent = true;
-  constexpr char kResolvedUrl[] = "fuchsia-pkg://fuchsia.com/echo_server_cpp/0";
+  constexpr char kResolvedUrl[] =
+      "fuchsia-pkg://fuchsia.com/sysmgr_integration_tests/0";
   const auto& args = resolver_service.args();
   EXPECT_EQ(std::get<0>(args), std::string(kResolvedUrl));
   EXPECT_EQ(std::get<1>(args), std::vector<std::string>{});
@@ -188,9 +191,7 @@
   // should succeed even though the update failed.
   zx::channel h1, h2;
   ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
-  auto launch_info = CreateLaunchInfo(
-      "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx",
-      std::move(h2));
+  auto launch_info = CreateLaunchInfo(kEchoServerURL, std::move(h2));
   auto controller = env_->CreateComponent(std::move(launch_info));
   fidl::examples::echo::EchoPtr echo;
   ConnectToServiceAt(std::move(h1), echo.NewRequest());
@@ -206,9 +207,7 @@
   ServiceProviderMock service_provider(&resolver_service);
   Init(&service_provider);
 
-  auto launch_url =
-      "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx";
-
+  auto launch_url = kEchoServerURL;
   {
     // Launch a component in the environment, and prove it started successfully
     // by trying to use a service offered by it.
diff --git a/garnet/bin/sysmgr/integration_tests/service_startup_test.cc b/garnet/bin/sysmgr/integration_tests/service_startup_test.cc
index 2ced778..52a9545c 100644
--- a/garnet/bin/sysmgr/integration_tests/service_startup_test.cc
+++ b/garnet/bin/sysmgr/integration_tests/service_startup_test.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <fidl/examples/echo/cpp/fidl.h>
 #include <lib/fdio/directory.h>
 #include <lib/fdio/fd.h>
 #include <lib/fdio/fdio.h>
@@ -43,38 +44,61 @@
 })";
   sysmgr_args.push_back(kSysmgrConfig);
 
-  auto context = sys::ComponentContext::Create();
+  auto environment_services = sys::ComponentContext::Create()->svc();
+
+  // Make fidl.examples.echo.Echo from our own environment available in appmgr's
+  // root realm.
+  fuchsia::sys::ServiceListPtr root_realm_services(
+      new fuchsia::sys::ServiceList);
+  root_realm_services->names =
+      std::vector<std::string>{fidl::examples::echo::Echo::Name_};
+  root_realm_services->host_directory =
+      environment_services->CloneChannel().TakeChannel();
 
   component::AppmgrArgs args{
       .pa_directory_request = h2.release(),
-      .environment_services = context->svc(),
+      .root_realm_services = std::move(root_realm_services),
+      .environment_services = std::move(environment_services),
       .sysmgr_url = "fuchsia-pkg://fuchsia.com/sysmgr#meta/sysmgr.cmx",
       .sysmgr_args = std::move(sysmgr_args),
       .run_virtual_console = false,
       .retry_sysmgr_crash = false};
   component::Appmgr appmgr(dispatcher(), std::move(args));
 
+  // h1 is connected to h2, which is injected above as appmgr's
+  // PA_DIRECTORY_REQUEST handle. appmgr hosts a directory on that handle, which
+  // includes a svc/ subdirectory, which in turn connects to the first realm's
+  // services. That first realm is the sys realm created by sysmgr, so
+  // sysmgr_svc ends up being a directory with all services in the sys realm.
   zx::channel svc_client, svc_server;
   ASSERT_EQ(ZX_OK, zx::channel::create(0, &svc_client, &svc_server));
   ASSERT_EQ(ZX_OK,
             fdio_service_connect_at(h1.get(), "svc", svc_server.release()));
-
-  ::test::sysmgr::InterfacePtr interface_ptr;
-  ASSERT_EQ(
-      ZX_OK,
-      fdio_service_connect_at(
-          svc_client.get(), ::test::sysmgr::Interface::Name_,
-          interface_ptr.NewRequest(dispatcher()).TakeChannel().release()));
+  sys::ServiceDirectory sysmgr_svc(std::move(svc_client));
 
   bool received_response = false;
   std::string response;
-  interface_ptr->Ping([&received_response, &response](fidl::StringPtr r) {
+  ::test::sysmgr::InterfacePtr interface_ptr;
+  ASSERT_EQ(ZX_OK, sysmgr_svc.Connect(interface_ptr.NewRequest(dispatcher())));
+
+  interface_ptr->Ping([&](fidl::StringPtr r) {
     received_response = true;
     response = r;
   });
-
-  RunLoopUntil([&received_response] { return received_response; });
+  RunLoopUntil([&] { return received_response; });
   EXPECT_EQ("test_sysmgr_service_startup", response);
+
+  const std::string echo_msg = "test string for echo";
+  received_response = false;
+  fidl::examples::echo::EchoPtr echo_ptr;
+  ASSERT_EQ(ZX_OK, sysmgr_svc.Connect(echo_ptr.NewRequest(dispatcher())));
+
+  echo_ptr->EchoString(echo_msg, [&](fidl::StringPtr r) {
+    received_response = true;
+    response = r;
+  });
+  RunLoopUntil([&] { return received_response; });
+  EXPECT_EQ(echo_msg, response);
 }
 
 }  // namespace
diff --git a/garnet/bin/ui/meta/gfx_apptests.cmx b/garnet/bin/ui/meta/gfx_apptests.cmx
index 449c0b1..0142bb8 100644
--- a/garnet/bin/ui/meta/gfx_apptests.cmx
+++ b/garnet/bin/ui/meta/gfx_apptests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/gfx_apptests"
     },
diff --git a/garnet/bin/ui/meta/gfx_pixeltests.cmx b/garnet/bin/ui/meta/gfx_pixeltests.cmx
index 140fe50..46cc91d 100644
--- a/garnet/bin/ui/meta/gfx_pixeltests.cmx
+++ b/garnet/bin/ui/meta/gfx_pixeltests.cmx
@@ -4,7 +4,10 @@
             "injected-services": {
                 "fuchsia.sysmem.Allocator": "fuchsia-pkg://fuchsia.com/sysmem_connector#meta/sysmem_connector.cmx",
                 "fuchsia.vulkan.loader.Loader": "fuchsia-pkg://fuchsia.com/vulkan_loader#meta/vulkan_loader.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {
diff --git a/garnet/bin/ui/meta/gfx_unittests.cmx b/garnet/bin/ui/meta/gfx_unittests.cmx
index 5f9c3b1..945285a 100644
--- a/garnet/bin/ui/meta/gfx_unittests.cmx
+++ b/garnet/bin/ui/meta/gfx_unittests.cmx
@@ -4,7 +4,10 @@
             "injected-services": {
                 "fuchsia.sysmem.Allocator": "fuchsia-pkg://fuchsia.com/sysmem_connector#meta/sysmem_connector.cmx",
                 "fuchsia.vulkan.loader.Loader": "fuchsia-pkg://fuchsia.com/vulkan_loader#meta/vulkan_loader.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {
diff --git a/garnet/bin/ui/meta/gfx_viewstate_apptests.cmx b/garnet/bin/ui/meta/gfx_viewstate_apptests.cmx
index 202979e..0139dbd 100644
--- a/garnet/bin/ui/meta/gfx_viewstate_apptests.cmx
+++ b/garnet/bin/ui/meta/gfx_viewstate_apptests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/gfx_viewstate_apptests"
     },
diff --git a/garnet/bin/ui/meta/input_unittests.cmx b/garnet/bin/ui/meta/input_unittests.cmx
index 124da00..e4271f1 100644
--- a/garnet/bin/ui/meta/input_unittests.cmx
+++ b/garnet/bin/ui/meta/input_unittests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/input_unittests"
     },
diff --git a/garnet/bin/ui/meta/root_presenter_tests.cmx b/garnet/bin/ui/meta/root_presenter_tests.cmx
index 119682b..5dc4019 100644
--- a/garnet/bin/ui/meta/root_presenter_tests.cmx
+++ b/garnet/bin/ui/meta/root_presenter_tests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/root_presenter_tests"
     },
diff --git a/garnet/bin/ui/meta/scenic_tests.cmx b/garnet/bin/ui/meta/scenic_tests.cmx
index 18e11b0..4e546e4 100644
--- a/garnet/bin/ui/meta/scenic_tests.cmx
+++ b/garnet/bin/ui/meta/scenic_tests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/gfx_unittests"
     },
diff --git a/garnet/bin/ui/meta/scenic_unittests.cmx b/garnet/bin/ui/meta/scenic_unittests.cmx
index af4fa3b..53f65d7 100644
--- a/garnet/bin/ui/meta/scenic_unittests.cmx
+++ b/garnet/bin/ui/meta/scenic_unittests.cmx
@@ -1,4 +1,11 @@
 {
+    "facets": {
+        "fuchsia.test": {
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
+        }
+    },
     "program": {
         "binary": "test/scenic_unittests"
     },
diff --git a/src/media/audio/audio/test/meta/audio_loopback_tests.cmx b/src/media/audio/audio/test/meta/audio_loopback_tests.cmx
index 0db8cb6..ca21b1e 100644
--- a/src/media/audio/audio/test/meta/audio_loopback_tests.cmx
+++ b/src/media/audio/audio/test/meta/audio_loopback_tests.cmx
@@ -7,7 +7,10 @@
                 "fuchsia.media.AudioDeviceEnumerator": "fuchsia-pkg://fuchsia.com/audio_core#meta/audio_core.cmx",
                 "fuchsia.virtualaudio.Control": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx",
                 "fuchsia.virtualaudio.Output": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {
diff --git a/src/media/audio/audio_core/test/meta/audio_device_tests.cmx b/src/media/audio/audio_core/test/meta/audio_device_tests.cmx
index 6913636..5b75fb5 100644
--- a/src/media/audio/audio_core/test/meta/audio_device_tests.cmx
+++ b/src/media/audio/audio_core/test/meta/audio_device_tests.cmx
@@ -7,7 +7,10 @@
                 "fuchsia.virtualaudio.Control": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx",
                 "fuchsia.virtualaudio.Input": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx",
                 "fuchsia.virtualaudio.Output": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {
diff --git a/src/media/audio/audio_core/test/meta/audio_fidl_tests.cmx b/src/media/audio/audio_core/test/meta/audio_fidl_tests.cmx
index 74ecb29..7dc6ad6 100644
--- a/src/media/audio/audio_core/test/meta/audio_fidl_tests.cmx
+++ b/src/media/audio/audio_core/test/meta/audio_fidl_tests.cmx
@@ -3,7 +3,10 @@
         "fuchsia.test": {
             "injected-services": {
                 "fuchsia.media.AudioCore": "fuchsia-pkg://fuchsia.com/audio_core#meta/audio_core.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {
diff --git a/src/media/audio/audio_core/test/meta/audio_pipeline_tests.cmx b/src/media/audio/audio_core/test/meta/audio_pipeline_tests.cmx
index 94336cb..53dd847 100644
--- a/src/media/audio/audio_core/test/meta/audio_pipeline_tests.cmx
+++ b/src/media/audio/audio_core/test/meta/audio_pipeline_tests.cmx
@@ -7,7 +7,10 @@
                 "fuchsia.virtualaudio.Control": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx",
                 "fuchsia.virtualaudio.Input": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx",
                 "fuchsia.virtualaudio.Output": "fuchsia-pkg://fuchsia.com/virtual_audio_service#meta/virtual_audio_service.cmx"
-            }
+            },
+            "system-services": [
+                "fuchsia.scheduler.ProfileProvider"
+            ]
         }
     },
     "program": {