[embedder] More bootstrapping.

- Add basic ViewProvider impl.
- Hack embedder platform to do inspect node logic.
- Move infra scripts to infra folder. They're still not connected.
- Break out a script to just build the engine artifacts without
  syncing them to a new git revision.

This enables us to run Dart apps from the session again using just
the workstation.qemu-x64 product bundle. I see
the "Hello from Dart!" log again.

Bug: 46971
Change-Id: I015642dbbd0624afb250204b897a5576da2478d8
diff --git a/README.md b/README.md
index bc18aa3..6a6eedc 100644
--- a/README.md
+++ b/README.md
@@ -82,11 +82,10 @@
 scripts/sync_engine_artifacts_to_revision.sh <ENGINE_COMMIT_SHA>
 ```
 
-A common workflow is to sync your Engine commit to the Flutter tool. To get your Flutter tool's Engine commit,
-you can do:
+A common workflow is to sync your Engine commit to the Flutter tool in this repository. To do this:
 
 ```sh
-cat $FUCHSIA_EMBEDDER_DIR/third_party/dart-pkg/internal/flutter/flutter/bin/internal/engine.version
+scripts/sync_engine_artifacts_to_revision.sh $(cat $FUCHSIA_EMBEDDER_DIR/third_party/dart-pkg/internal/flutter/flutter/bin/internal/engine.version)
 ```
 
 
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
index 837327f..a889f19 100644
--- a/WORKSPACE.bazel
+++ b/WORKSPACE.bazel
@@ -26,10 +26,10 @@
 
 fuchsia_sdk_repository(
     name = "fuchsia_sdk",
-    cipd_tag = "version:8.20220516.2.1",
+    cipd_tag = "version:8.20220520.1.1",
     sha256 = {
-        "linux": "174fc1f1654a6201ff4080030b776a1b8b1aaaa3d0500ee3f3aa0068bb2a4de2",
-        "mac": "b7f932f25ea76f163a74707de25f5fb83de81bb92edb57ab29f433601e6a839c",
+        "linux": "1700f5e03daeb34e950912f225cacf737f8ebcfef24dfe9051444a3c99e7e935",
+        "mac": "1503e6b4578073df6afcd4c7a9e3a58d747cd7a5b0ebb00f7602745f70d96eee",
     },
 )
 
@@ -59,5 +59,5 @@
 
 flutter_register_toolchains(
     dart_tag = "git_revision:e59c04ff550d5343f626a0fca4006e4b1e6c09da",
-    flutter_tag = "git_revision:b42972f3c1bea9762774bd3b142e1b37fe65a485",
+    flutter_tag = "git_revision:f9c6208687e0d1796710d93862b170292c3e5ee1",
 )
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
deleted file mode 100755
index 9b439af..0000000
--- a/scripts/bootstrap.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-
-# Copyright 2021 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.
-
-# TODO(https://fxbug.dev/90066): Delete this file once we don't need a generated
-# c++ toolchain from //third_party/sdk-integration/bazel_rules_generator/... anymore.
-
-set -e
-
-# This script is used to fetch the prebuilt that is needed by flutter embedder build.
-
-REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/..
-readonly REPO_ROOT="${REPO_ROOT}"
-
-# The following is temporary to support the transition to the generated
-# Bazel SDK
-SDK_DOWNLOAD_URL=
-
-# Note: This tag needs to be kept in sync with the version in WORKSPACE.bazel until
-# the transition of the rules out of this repo is complete.
-SDK_VERSION_TAG="version:6.20211029.2.1"
-KERNEL_NAME=$(uname -s | tr '[:upper:]' '[:lower:]')
-case "${KERNEL_NAME}" in
-  linux)
-    SDK_DOWNLOAD_URL="https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64/+/${SDK_VERSION_TAG}"
-    ;;
-  darwin)
-    SDK_DOWNLOAD_URL="https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/mac-amd64/+/${SDK_VERSION_TAG}"
-    ;;
-  *)
-    >&2 echo "The fuchsia sdk not supported on ${KERNEL_NAME}"
-    exit 1
-esac
-
-TMP_DOWNLOAD_DIR="$(mktemp -d)"
-trap 'rm -rf "${TMP_DOWNLOAD_DIR}"' EXIT
-
-generate_rules_fuchsia() {
-  echo "Downloading prebuilt SDK"
-  curl -sL "${SDK_DOWNLOAD_URL}" -o "${TMP_DOWNLOAD_DIR}/sdk.zip"
-
-  echo "Unzipping SDK Archive"
-  unzip -q "${TMP_DOWNLOAD_DIR}/sdk.zip" -d "${REPO_ROOT}/sdk"
-
-  echo "Generating rules fuchsia!"
-
-  pushd "${REPO_ROOT}/third_party/sdk-integration/bazel_rules_generator/" > /dev/null || exit
-  ./generate.py \
-    --directory "${REPO_ROOT}/sdk" \
-    --output "${REPO_ROOT}/rules_fuchsia_transitional"
-
-  popd > /dev/null || exit
-
-  echo "Done generating rules fuchsia."
-}
-
-main() {
-  generate_rules_fuchsia
-}
-
-main "$@"
diff --git a/scripts/build_and_copy_engine_artifacts.sh b/scripts/build_and_copy_engine_artifacts.sh
new file mode 100755
index 0000000..255fb06
--- /dev/null
+++ b/scripts/build_and_copy_engine_artifacts.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+#
+# 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.
+#
+# Builds and copies artifacts for the Flutter embedder from your
+# local source of the Flutter Engine repository.
+#
+# Usage:
+#   build_and_copy_engine_artifacts.sh
+#
+# Prerequisites:
+#   1. $ENGINE_DIR is set to the src/ directory of your flutter/engine checkout.
+#   2. $FUCHSIA_EMBEDDER_DIR is set to your flutter-embedder.git checkout.
+#   3. $DEPOT_TOOLS is set to your depot_tools directory.
+
+# Returns true if colors are supported.
+function is-stderr-tty {
+  [[ -t 2 ]]
+}
+
+# Prints a line to stderr with a green INFO: prefix.
+function echo-info {
+  if is-stderr-tty; then
+    echo -e >&2 "\033[1;32mINFO:\033[0m $*"
+  else
+    echo -e >&2 "INFO: $*"
+  fi
+}
+
+echo-info "Building the Flutter Engine embedding for Fuchsia (libflutter_engine.so)..."
+"${ENGINE_DIR}"/flutter/tools/gn --fuchsia --embedder-for-target --unopt
+out_dir="${ENGINE_DIR}"/out/fuchsia_debug_unopt_x64
+"${DEPOT_TOOLS}"/ninja -C "${out_dir}"
+
+echo-info "Copying Flutter Engine artifacts to ${FUCHSIA_EMBEDDER_DIR}/src/embedder..."
+cp "${out_dir}"/libflutter_engine.so "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine/libflutter_engine.so
+cp "${ENGINE_DIR}"/flutter/shell/platform/embedder/embedder.h "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine/embedder.h
diff --git a/scripts/build_and_run_sample_app.sh b/scripts/build_and_run_sample_app.sh
index bfe0f3a..fa0652c 100755
--- a/scripts/build_and_run_sample_app.sh
+++ b/scripts/build_and_run_sample_app.sh
@@ -10,8 +10,9 @@
 # TODO(akbiggs): Port this workflow to Bazel.
 
 set -e # Exit if any program returns an error.
-APP_NAME=flutter_sample_app
-FAR_DEBUG_DIR=/tmp/"${APP_NAME}"_far_contents
+app_name=flutter_sample_app
+far_debug_dir=/tmp/"${app_name}"_far_contents
+far_tool="${FUCHSIA_EMBEDDER_DIR}"/bazel-flutter-embedder/external/fuchsia_sdk/tools/x64/far
 
 function is-stderr-tty {
   [[ -t 2 ]]
@@ -29,11 +30,17 @@
 pushd "${FUCHSIA_EMBEDDER_DIR}"
 
 echo-info "Building Flutter sample app bundle."
-cd "${FUCHSIA_EMBEDDER_DIR}"/src/examples/"${APP_NAME}"
+cd "${FUCHSIA_EMBEDDER_DIR}"/src/examples/"${app_name}"
 "${FUCHSIA_EMBEDDER_DIR}"/tools/flutter build bundle
 
 echo-info "Running Flutter sample app."
 cd "${FUCHSIA_EMBEDDER_DIR}"
-bazel run --config=fuchsia_x64 //src/examples/"${APP_NAME}":"${APP_NAME}"_pkg.component -- --session
+bazel run --config=fuchsia_x64 //src/examples/"${app_name}":"${app_name}"_pkg.component -- --session
+
+echo-info "Package contents for debugging:"
+"${far_tool}" extract --archive="${FUCHSIA_EMBEDDER_DIR}"/bazel-bin/src/examples/"${app_name}"/"${app_name}".far --output="${far_debug_dir}"
+"${far_tool}" extract --archive="${far_debug_dir}"/meta.far --output="${far_debug_dir}"
+cat "${far_debug_dir}"/meta/contents
+rm -r "${far_debug_dir}"
 
 popd
diff --git a/scripts/build.sh b/scripts/infra/build.sh
similarity index 100%
rename from scripts/build.sh
rename to scripts/infra/build.sh
diff --git a/scripts/upload.sh b/scripts/infra/upload.sh
similarity index 100%
rename from scripts/upload.sh
rename to scripts/infra/upload.sh
diff --git a/scripts/sync_engine_artifacts_to_revision.sh b/scripts/sync_engine_artifacts_to_revision.sh
index 189d7e7..1a7b234 100755
--- a/scripts/sync_engine_artifacts_to_revision.sh
+++ b/scripts/sync_engine_artifacts_to_revision.sh
@@ -1,5 +1,12 @@
 #!/bin/bash
 #
+# 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.
+#
+# Syncs the Flutter Engine artifacts in this repository to artifacts built
+# at a specified commit.
+#
 # Usage:
 #   sync_engine_artifacts_to_commit.sh <engine_commit>
 #
@@ -27,14 +34,17 @@
 
 pushd "${ENGINE_DIR}"
 
+# Sync Flutter to specified revision.
 echo-info "Syncing ${ENGINE_DIR}/flutter to ${engine_revision}..."
 pushd flutter
 git checkout "${engine_revision}"
-popd
+popd  # flutter
 
 echo-info "Syncing ${ENGINE_DIR} dependencies..."
 gclient sync -D
 
+# Get buildroot fix.
+# TODO(akbiggs): Submit this fix.
 buildroot_fix=c7deba3773ed645c29f4518cc3990bc02f0f53cd
 pushd build
 if ! git merge-base --is-ancestor "${buildroot_fix}" HEAD
@@ -45,10 +55,13 @@
   git fetch akbiggs
   git cherry-pick -c "${buildroot_fix}"
 fi
-popd
+popd  # build
 
-jit_snapshot_fix=d79531e15a1b04d5e68c7ad87775cb594727d7b0
 pushd flutter
+
+# Get JIT snapshot fix.
+# TODO(akbiggs): Submit this fix.
+jit_snapshot_fix=d79531e15a1b04d5e68c7ad87775cb594727d7b0
 if ! git merge-base --is-ancestor "${jit_snapshot_fix}" HEAD
 then
   echo-info "Cherry-picking https://github.com/flutter/engine/pull/33189 into ${ENGINE_DIR}/flutter to work around JIT snapshot loading issue..."
@@ -56,22 +69,29 @@
   git fetch akbiggs
   git cherry-pick -c "${jit_snapshot_fix}"
 fi
-popd
+
+# Get inspect node fix.
+# TODO(akbiggs): Submit this fix.
+inspect_node_fix=3b8de94b1347d2f7c3e5e33933866ba8140abdc1
+if ! git merge-base --is-ancestor "${inspect_node_fix}" HEAD
+then
+  echo-info "Cherry-picking https://github.com/flutter/engine/pull/33472 into ${ENGINE_DIR}/flutter to set Dart VM inspect node for Fuchsia..."
+  git remote add akbiggs https://github.com/akbiggs/engine
+  git fetch akbiggs
+  git cherry-pick -c "${inspect_node_fix}"
+fi
+
+popd  # flutter
 
 # Fail on any error.
 # We start failing here because the previous commands throw errors even
 # when things are fine.
 set -e
 
-echo-info "Building the Flutter Engine embedding for Fuchsia (libflutter_engine.so)..."
-"${ENGINE_DIR}"/flutter/tools/gn --fuchsia --embedder-for-target --unopt
-out_dir="${ENGINE_DIR}"/out/fuchsia_debug_unopt_x64
-"${DEPOT_TOOLS}"/ninja -C "${out_dir}"
-
-echo-info "Copying Flutter Engine artifacts to ${FUCHSIA_EMBEDDER_DIR}/src/embedder..."
-cp "${out_dir}"/libflutter_engine.so "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/libflutter_engine.so
-cp "${ENGINE_DIR}"/flutter/shell/platform/embedder/embedder.h "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/embedder.h
-echo "${engine_revision}" > "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine_revision
+# Build and copy over the artifacts we need and update our
+# revision.
+"${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh
+echo "${engine_revision}" > "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine/engine_revision
 
 echo-info "Done! Engine artifacts updated to ${engine_revision}."
-popd
+popd  # ${ENGINE_DIR}
diff --git a/src/embedder/BUILD.bazel b/src/embedder/BUILD.bazel
index 25c3a25..9eb6649 100644
--- a/src/embedder/BUILD.bazel
+++ b/src/embedder/BUILD.bazel
@@ -10,7 +10,8 @@
     "fuchsia_component_manifest",
 )
 
-# ELF binary that takes Flutter app assets and runs a Flutter app.
+# ELF binary that takes the path to Flutter app assets as an argument
+# and runs the Flutter app defined by those assets.
 fuchsia_cc_binary(
     name = "embedder",
     visibility = ["//visibility:public"],
@@ -20,8 +21,10 @@
     deps = [
         "//src/embedder/engine:embedder_header",
         "//src/embedder/engine:libflutter_engine",
+        "@fuchsia_sdk//fidl/fuchsia.ui.app:fuchsia.ui.app_cc",
         "@fuchsia_sdk//pkg/async-loop-default",
         "@fuchsia_sdk//pkg/async-loop-cpp",
+        "@fuchsia_sdk//pkg/sys_cpp",
         "@fuchsia_sdk//pkg/syslog",
     ],
 )
@@ -30,5 +33,8 @@
     name = "embedder_manifest",
     visibility = ["//visibility:public"],
     src = "meta/embedder.cml",
-    includes = ["@fuchsia_sdk//pkg/syslog:client"],
+    includes = [
+        "@fuchsia_sdk//pkg/syslog:client",
+        "@fuchsia_sdk//pkg/vulkan:client",
+    ],
 )
diff --git a/src/embedder/engine/BUILD.bazel b/src/embedder/engine/BUILD.bazel
index 80f8aa0..fe3f73e 100644
--- a/src/embedder/engine/BUILD.bazel
+++ b/src/embedder/engine/BUILD.bazel
@@ -23,10 +23,18 @@
     name = "libflutter_engine",
     srcs = ["libflutter_engine.so"],
     visibility = ["//src/embedder:__pkg__"],
+    deps = [
+        "@fuchsia_sdk//pkg/memfs",
+        "@fuchsia_sdk//pkg/vulkan",
+    ]
 )
 
+# Package resource to include libflutter_engine into a Fuchsia package's
+# libraries.
+# You must include this in your package's dependencies if your package's binary
+# has a dependency on `:libflutter_engine`.
 fuchsia_package_resource(
-    name = "flutter_engine_pkg_resource",
+    name = "libflutter_engine_pkg_resource",
     visibility = ["//visibility:public"],
     src = ":libflutter_engine.so",
     dest = "lib/libflutter_engine.so",
diff --git a/src/embedder/engine/engine_revision b/src/embedder/engine/engine_revision
index 2c59ebd..daef129 100644
--- a/src/embedder/engine/engine_revision
+++ b/src/embedder/engine/engine_revision
@@ -1 +1 @@
-94a5895388f79e17b7bc8c91edebf461e57c2f01
+a1e7905dc6025ff4633ac3dda7d165e8e4dd76e1
diff --git a/src/embedder/engine/libflutter_engine.so b/src/embedder/engine/libflutter_engine.so
index 6e0da88..d0a0468 100755
--- a/src/embedder/engine/libflutter_engine.so
+++ b/src/embedder/engine/libflutter_engine.so
Binary files differ
diff --git a/src/embedder/main.cc b/src/embedder/main.cc
index 14ce931..2562222 100644
--- a/src/embedder/main.cc
+++ b/src/embedder/main.cc
@@ -6,10 +6,16 @@
 //
 // Usage: ./main <path_to_flutter_asset_bundle>
 
+#include <fuchsia/ui/app/cpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
+#include <lib/async/default.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/sys/cpp/component_context.h>
 #include <lib/syslog/global.h>
 #include <string>
+#include <zircon/status.h>
 
 #include "src/embedder/engine/embedder.h"
 
@@ -17,6 +23,47 @@
 
 constexpr char kLogTag[] = "flutter_embedder";
 
+// TODO(akbiggs): This is just being used to verify that we can
+// create and bind things on the component context. We should
+// replace this with an actual ViewProvider impl.
+class DummyViewProvider : public fuchsia::ui::app::ViewProvider {
+public:
+  DummyViewProvider() {}
+  ~DummyViewProvider() override {}
+  DummyViewProvider(const DummyViewProvider &) = delete;
+  DummyViewProvider &operator=(const DummyViewProvider &) = delete;
+
+  void CreateView(
+      zx::eventpair token,
+      fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
+      fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services)
+      override {
+    FX_LOG(INFO, kLogTag, "ViewProvider::CreateView");
+  }
+
+  void CreateViewWithViewRef(zx::eventpair view_token,
+                             fuchsia::ui::views::ViewRefControl control_ref,
+                             fuchsia::ui::views::ViewRef view_ref) override {
+    FX_LOG(INFO, kLogTag, "ViewProvider::CreateViewWithViewRef");
+  }
+
+  void CreateView2(fuchsia::ui::app::CreateView2Args view_args) override {
+    FX_LOG(INFO, kLogTag, "ViewProvider::CreateView2");
+  }
+};
+
+// State for the embedder. The engine callbacks
+// get this data as an argument so we can access
+// this data from our implementation of the callbacks.
+struct EmbedderData {
+  // WARNING: |component_context| MUST BE THE FIRST FIELD OF THIS DATA.
+  // We do a terrible hack in https://github.com/flutter/engine/pull/33472 that
+  // requires reading this field to work around fxb/75282 to set the inspect
+  // node inside the embedder on the Fuchsia platform.
+  // TODO(fxb/75282): Properly fix this and remove the terrible hack.
+  std::unique_ptr<sys::ComponentContext> component_context;
+};
+
 bool FuchsiaPresentSoftwareSurface(void *user_data, const void *allocation,
                                    size_t row_bytes, size_t height) {
   // TODO(akbiggs): Present the surface to the screen.
@@ -32,7 +79,7 @@
   FX_LOG(INFO, tag, message);
 }
 
-bool RunFlutterApp(const char *assets_path) {
+bool RunFlutterApp(const char *assets_path, EmbedderData *embedder_data) {
   FlutterRendererConfig renderer_config = {
       .type = kSoftware,
       .software =
@@ -52,12 +99,9 @@
   // TODO(akbiggs): Store this FlutterEngine instance somewhere instead of
   // throwing it away.
   FlutterEngine engine;
-  FlutterEngineResult result = FlutterEngineRun(
-      FLUTTER_ENGINE_VERSION, &renderer_config, &project_args,
-      // user_data is an arbitrary object that we can pass around to engine
-      // callbacks. When we need to make those callbacks change state in our
-      // embedder we should pass a pointer to a collection of our state here.
-      nullptr /* user_data */, &engine);
+  FlutterEngineResult result =
+      FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config, &project_args,
+                       embedder_data, &engine);
 
   if (result != kSuccess || engine == nullptr) {
     FX_LOGF(ERROR, kLogTag, "Could not run the Flutter Engine. Error code: %d",
@@ -77,9 +121,54 @@
   }
   const char *assets_path = argv[1];
 
+  EmbedderData embedder_data = {
+      .component_context = sys::ComponentContext::Create(),
+  };
+
+  // TODO(akbiggs): Remove debug logs once we're sure this is stable.
+  FX_LOG(INFO, kLogTag, "Running Flutter app.");
+
+  // Note: Serving the component context must happen after RunFlutterApp
+  // because the embedder platform has a hack that adds inspect data into the
+  // Dart VM using the component context
+  // (https://github.com/flutter/engine/pull/33472).
+  RunFlutterApp(assets_path, &embedder_data);
+
+  FX_LOG(INFO, kLogTag, "Binding ViewProvider.");
+  DummyViewProvider view_provider;
+  fidl::BindingSet<fuchsia::ui::app::ViewProvider> view_provider_bindings;
+  zx_status_t status =
+      embedder_data.component_context->outgoing()
+          ->AddPublicService<fuchsia::ui::app::ViewProvider>(
+              [&view_provider, &view_provider_bindings](
+                  fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
+                      request) {
+                FX_LOG(INFO, kLogTag, "Adding ViewProvider binding.");
+
+                view_provider_bindings.AddBinding(&view_provider,
+                                                  std::move(request));
+              });
+  if (status != ZX_OK) {
+    FX_LOGF(ERROR, kLogTag, "Failed to add ViewProvider service: %s",
+            zx_status_get_string(status));
+  }
+
+  // Our run loop's dispatcher must be used as the dispatcher for serving
+  // the component context in order for requests handlers to get called while
+  // we're looping.
+  FX_LOG(INFO, kLogTag, "Serving component context.");
   async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
-  RunFlutterApp(assets_path);
+  status = embedder_data.component_context->outgoing()->ServeFromStartupInfo(
+      loop.dispatcher());
+  if (status != ZX_OK) {
+    FX_LOGF(ERROR, kLogTag, "Failed to serve component context: %s",
+            zx_status_get_string(status));
+  }
+
+  // Loop until we're done.
+  FX_LOG(INFO, kLogTag, "Looping.");
   loop.Run();
 
+  FX_LOG(INFO, kLogTag, "Done looping.");
   return EXIT_SUCCESS;
 }
diff --git a/src/embedder/meta/embedder.cml b/src/embedder/meta/embedder.cml
index 970ac11..2ffd351 100644
--- a/src/embedder/meta/embedder.cml
+++ b/src/embedder/meta/embedder.cml
@@ -1,15 +1,54 @@
 {
-    include: [ "syslog/client.shard.cml" ],
+    include: [
+        "syslog/client.shard.cml",
+        "vulkan/client.shard.cml",
+    ],
 
     program: {
+        // The embedder is a ELF binary that runs using the ELF runner.
         runner: "elf",
         binary: "bin/embedder",
+
+        // To run a Flutter app with the embedder, compile the Flutter
+        // app into an asset bundle and put that bundle in this location
+        // in the component's package.
         args: ["/pkg/data/flutter_assets"],
 
+        // Required for `std::cout` and `std::cerr` to print to
+        // `ffx log`.
         forward_stdout_to: "log",
         forward_stderr_to: "log",
 
         // Required for JIT execution.
         job_policy_ambient_mark_vmo_exec: "true",
     },
+
+    capabilities: [
+        {
+            protocol: [
+                // For rendering.
+                "fuchsia.ui.app.ViewProvider",
+            ],
+        },
+    ],
+
+    expose: [
+        {
+            protocol: [
+                // For rendering.
+                "fuchsia.ui.app.ViewProvider",
+            ],
+            from: "self",
+            to: "parent"
+        },
+    ],
+
+    use: [
+        {
+            protocol: [
+                // For the Dart VM service.
+                "fuchsia.posix.socket.Provider",
+            ]
+        },
+    ],
 }
diff --git a/src/examples/flutter_sample_app/BUILD.bazel b/src/examples/flutter_sample_app/BUILD.bazel
index cec1692..4520f59 100644
--- a/src/examples/flutter_sample_app/BUILD.bazel
+++ b/src/examples/flutter_sample_app/BUILD.bazel
@@ -44,6 +44,6 @@
     visibility = ["//visibility:public"],
     deps = [
         ":component",
-        "//src/embedder/engine:flutter_engine_pkg_resource",
+        "//src/embedder/engine:libflutter_engine_pkg_resource",
     ],
 )
diff --git a/src/examples/flutter_sample_app/pubspec.lock b/src/examples/flutter_sample_app/pubspec.lock
index 2aa44f8..72de359 100644
--- a/src/examples/flutter_sample_app/pubspec.lock
+++ b/src/examples/flutter_sample_app/pubspec.lock
@@ -22,13 +22,6 @@
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.2.1"
-  charcode:
-    dependency: transitive
-    description:
-      name: charcode
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "1.3.1"
   clock:
     dependency: transitive
     description:
@@ -141,7 +134,7 @@
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.0"
+    version: "1.1.1"
   term_glyph:
     dependency: transitive
     description:
diff --git a/third_party/dart-pkg/internal/flutter/flutter b/third_party/dart-pkg/internal/flutter/flutter
index ac33330..1e1f4bc 160000
--- a/third_party/dart-pkg/internal/flutter/flutter
+++ b/third_party/dart-pkg/internal/flutter/flutter
@@ -1 +1 @@
-Subproject commit ac3333094af2b4e51163167546777086e5bd7b79
+Subproject commit 1e1f4bcfb56105912a90ffa1a3a317dfb724612b
diff --git a/third_party/sdk-integration b/third_party/sdk-integration
index 1f2296d..eba8db7 160000
--- a/third_party/sdk-integration
+++ b/third_party/sdk-integration
@@ -1 +1 @@
-Subproject commit 1f2296dc876d3de3f09c87b9e01fb1355b7fcec4
+Subproject commit eba8db745bddc4fefeb4692ba837caa85d387a08