diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build
index f45622cf9be0022938a7edbd3fae91905eebc5d6..757e68af49eb98471d9eaf1926a73c2114eb6cd1 100644
--- a/pressure-vessel/meson.build
+++ b/pressure-vessel/meson.build
@@ -205,6 +205,8 @@ executable(
     'runtime.c',
     'runtime.h',
     'wrap.c',
+    'wrap-flatpak.c',
+    'wrap-flatpak.h',
     'wrap-setup.c',
     'wrap-setup.h',
   ] + enums,
diff --git a/pressure-vessel/wrap-flatpak.c b/pressure-vessel/wrap-flatpak.c
new file mode 100644
index 0000000000000000000000000000000000000000..f8dbb49e3b8a7a77c7f669cdb4b4ad5b4fec4135
--- /dev/null
+++ b/pressure-vessel/wrap-flatpak.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2020-2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "wrap-flatpak.h"
+
+#include "libglnx/libglnx.h"
+
+#include "utils.h"
+
+static gboolean
+check_launch_on_host (const char *launch_executable,
+                      GError **error)
+{
+  g_autofree gchar *child_stdout = NULL;
+  g_autofree gchar *child_stderr = NULL;
+  int wait_status;
+  const char *test_argv[] =
+  {
+    NULL,
+    "--bus-name=org.freedesktop.Flatpak",
+    "--",
+    "true",
+    NULL
+  };
+
+  test_argv[0] = launch_executable;
+
+  if (!g_spawn_sync (NULL,  /* cwd */
+                     (gchar **) test_argv,
+                     NULL,  /* environ */
+                     G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
+                     NULL, NULL,    /* child setup */
+                     &child_stdout,
+                     &child_stderr,
+                     &wait_status,
+                     error))
+    {
+      return FALSE;
+    }
+
+  if (wait_status != 0)
+    {
+      pv_log_failure ("Cannot run commands on host system: wait status %d",
+                 wait_status);
+
+      if (child_stdout != NULL && child_stdout[0] != '\0')
+        pv_log_failure ("Output:\n%s", child_stdout);
+
+      if (child_stderr != NULL && child_stderr[0] != '\0')
+        pv_log_failure ("Diagnostic output:\n%s", child_stderr);
+
+      return glnx_throw (error, "Unable to run a command on the host system");
+    }
+
+  return TRUE;
+}
+
+/*
+ * pv_wrap_check_flatpak:
+ * @tools_dir: Path to .../pressure-vessel/bin/
+ * @subsandbox_out: (out) (not optional) (nullable): Used to return
+ *  an adverb command that will launch its arguments in a sub-sandbox,
+ *  or %NULL if not using sub-sandboxing
+ * @run_on_host_out: (out) (not optional) (nullable): Used to return
+ *  an adverb command that will launch its arguments on the host system,
+ *  or %NULL if not using sandbox escape
+ *
+ * Check that we are running under Flatpak and can launch the game somehow.
+ * On success, exactly one of the `(out)` parameters will be set to non-%NULL.
+ *
+ * Returns: %TRUE on success
+ */
+gboolean
+pv_wrap_check_flatpak (const char *tools_dir,
+                       FlatpakBwrap **subsandbox_out,
+                       FlatpakBwrap **run_on_host_out,
+                       GError **error)
+{
+  g_autoptr(FlatpakBwrap) subsandbox = NULL;
+  g_autoptr(FlatpakBwrap) run_on_host = NULL;
+  g_autofree gchar *launch_executable = NULL;
+
+  g_return_val_if_fail (tools_dir != NULL, FALSE);
+  g_return_val_if_fail (subsandbox_out != NULL, FALSE);
+  g_return_val_if_fail (*subsandbox_out == NULL, FALSE);
+  g_return_val_if_fail (run_on_host_out != NULL, FALSE);
+  g_return_val_if_fail (*run_on_host_out == NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  launch_executable = g_build_filename (tools_dir,
+                                        "pressure-vessel-launch",
+                                        NULL);
+
+  /* Deliberately not documented: only people who are in a position
+   * to run their own modified versions of Flatpak and pressure-vessel
+   * should be using this, and those people can find this in the
+   * source code */
+  if (g_getenv ("PRESSURE_VESSEL_FLATPAK_PR4018") != NULL)
+    {
+      g_warning ("Assuming your version of Flatpak contains unmerged "
+                 "changes (#4018, #4125, #4126, #4093)");
+      /* Use a sub-sandbox */
+      subsandbox = flatpak_bwrap_new (flatpak_bwrap_empty_env);
+      flatpak_bwrap_add_arg (subsandbox, launch_executable);
+      /* Tell pressure-vessel-launch to send its whole environment
+       * to the subsandbox, except for the parts that we edit later.
+       * This effectively matches bwrap's behaviour. */
+      flatpak_bwrap_add_arg (subsandbox, "--pass-env-matching=*");
+      flatpak_bwrap_add_arg (subsandbox,
+                             "--bus-name=org.freedesktop.portal.Flatpak");
+    }
+  /* Also deliberately not documented */
+  else if (g_getenv ("PRESSURE_VESSEL_FLATPAK_SANDBOX_ESCAPE") != NULL)
+    {
+      g_warning ("Assuming permissions have been set to allow Steam "
+                 "to escape from the Flatpak sandbox");
+
+      /* If we have permission to escape from the sandbox, we'll do that,
+       * and launch bwrap that way */
+      run_on_host = flatpak_bwrap_new (flatpak_bwrap_empty_env);
+      flatpak_bwrap_add_arg (run_on_host,
+                             launch_executable);
+      flatpak_bwrap_add_arg (run_on_host,
+                             "--bus-name=org.freedesktop.Flatpak");
+
+      /* If we can't launch a command on the host, just fail. */
+      if (!check_launch_on_host (launch_executable, error))
+        return FALSE;
+    }
+  else
+    {
+      return glnx_throw (error,
+                         "pressure-vessel (SteamLinuxRuntime) cannot be run "
+                         "in a Flatpak environment. For Proton 5.13+, "
+                         "unofficial community builds that do not use "
+                         "pressure-vessel are available.");
+    }
+
+  /* Exactly one of them is non-NULL on success */
+  g_assert ((subsandbox != NULL) + (run_on_host != NULL) == 1);
+
+  *subsandbox_out = g_steal_pointer (&subsandbox);
+  *run_on_host_out = g_steal_pointer (&run_on_host);
+  return TRUE;
+}
diff --git a/pressure-vessel/wrap-flatpak.h b/pressure-vessel/wrap-flatpak.h
new file mode 100644
index 0000000000000000000000000000000000000000..f513b493ed82c962c941195e20c2aca4de500d14
--- /dev/null
+++ b/pressure-vessel/wrap-flatpak.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2020-2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib.h>
+
+#include "libglnx/libglnx.h"
+
+#include "flatpak-bwrap-private.h"
+
+gboolean pv_wrap_check_flatpak (const char *tools_dir,
+                                FlatpakBwrap **flatpak_subsandbox,
+                                FlatpakBwrap **flatpak_run_on_host,
+                                GError **error);
diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c
index 6f938585825b401bdd6d157c27655d695ad3c182..38034ed22dfaf76be404b14819383ca9f2d0042f 100644
--- a/pressure-vessel/wrap.c
+++ b/pressure-vessel/wrap.c
@@ -43,6 +43,7 @@
 #include "flatpak-utils-private.h"
 #include "runtime.h"
 #include "utils.h"
+#include "wrap-flatpak.h"
 #include "wrap-interactive.h"
 #include "wrap-setup.h"
 
@@ -208,54 +209,6 @@ check_bwrap (const char *tools_dir,
   return NULL;
 }
 
-static gboolean
-check_launch_on_host (const char *launch_executable,
-                      GError **error)
-{
-  g_autofree gchar *child_stdout = NULL;
-  g_autofree gchar *child_stderr = NULL;
-  int wait_status;
-  const char *test_argv[] =
-  {
-    NULL,
-    "--bus-name=org.freedesktop.Flatpak",
-    "--",
-    "true",
-    NULL
-  };
-
-  test_argv[0] = launch_executable;
-
-  if (!g_spawn_sync (NULL,  /* cwd */
-                     (gchar **) test_argv,
-                     NULL,  /* environ */
-                     G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
-                     NULL, NULL,    /* child setup */
-                     &child_stdout,
-                     &child_stderr,
-                     &wait_status,
-                     error))
-    {
-      return FALSE;
-    }
-
-  if (wait_status != 0)
-    {
-      pv_log_failure ("Cannot run commands on host system: wait status %d",
-                 wait_status);
-
-      if (child_stdout != NULL && child_stdout[0] != '\0')
-        pv_log_failure ("Output:\n%s", child_stdout);
-
-      if (child_stderr != NULL && child_stderr[0] != '\0')
-        pv_log_failure ("Diagnostic output:\n%s", child_stderr);
-
-      return glnx_throw (error, "Unable to run a command on the host system");
-    }
-
-  return TRUE;
-}
-
 /* Nvidia Vulkan ray-tracing requires to load the `nvidia_uvm.ko` kernel
  * module, and this is usually done in `libcuda.so.1` by running the setuid
  * binary `nvidia-modprobe`. But when we are inside a container we don't bind
@@ -1368,7 +1321,6 @@ main (int argc,
   g_autoptr(FlatpakBwrap) argv_in_container = NULL;
   g_autoptr(FlatpakBwrap) final_argv = NULL;
   g_autoptr(FlatpakExports) exports = NULL;
-  g_autofree gchar *launch_executable = NULL;
   g_autofree gchar *bwrap_executable = NULL;
   g_autofree gchar *cwd_p = NULL;
   g_autofree gchar *cwd_l = NULL;
@@ -1797,60 +1749,14 @@ main (int argc,
   /* If we are in a Flatpak environment we can't use bwrap directly */
   if (is_flatpak_env)
     {
+      if (!pv_wrap_check_flatpak (tools_dir,
+                                  &flatpak_subsandbox,
+                                  &flatpak_run_on_host,
+                                  error))
+        goto out;
 
-      launch_executable = g_build_filename (tools_dir,
-                                            "pressure-vessel-launch",
-                                            NULL);
       /* Assume "bwrap" to exist in the host system and to be in its PATH */
       bwrap_executable = g_strdup ("bwrap");
-
-      /* Deliberately not documented: only people who are in a position
-       * to run their own modified versions of Flatpak and pressure-vessel
-       * should be using this, and those people can find this in the
-       * source code */
-      if (g_getenv ("PRESSURE_VESSEL_FLATPAK_PR4018") != NULL)
-        {
-          g_warning ("Assuming your version of Flatpak contains unmerged "
-                     "changes (#4018, #4125, #4126, #4093)");
-
-          /* Use a sub-sandbox */
-          flatpak_subsandbox = flatpak_bwrap_new (flatpak_bwrap_empty_env);
-          flatpak_bwrap_add_arg (flatpak_subsandbox,
-                                 launch_executable);
-          /* Tell pressure-vessel-launch to send its whole environment
-           * to the subsandbox, except for the parts that we edit later.
-           * This effectively matches bwrap's behaviour. */
-          flatpak_bwrap_add_arg (flatpak_subsandbox, "--pass-env-matching=*");
-          flatpak_bwrap_add_arg (flatpak_subsandbox,
-                                 "--bus-name=org.freedesktop.portal.Flatpak");
-        }
-      /* Also deliberately not documented */
-      else if (g_getenv ("PRESSURE_VESSEL_FLATPAK_SANDBOX_ESCAPE") != NULL)
-        {
-          g_warning ("Assuming permissions have been set to allow Steam "
-                     "to escape from the Flatpak sandbox");
-
-          /* If we have permission to escape from the sandbox, we'll do that,
-           * and launch bwrap that way */
-          flatpak_run_on_host = flatpak_bwrap_new (flatpak_bwrap_empty_env);
-          flatpak_bwrap_add_arg (flatpak_run_on_host,
-                                 launch_executable);
-          flatpak_bwrap_add_arg (flatpak_run_on_host,
-                                 "--bus-name=org.freedesktop.Flatpak");
-
-          /* If we can't launch a command on the host, just fail. */
-          if (!check_launch_on_host (launch_executable, error))
-            goto out;
-        }
-      else
-        {
-          glnx_throw (error,
-                      "pressure-vessel (SteamLinuxRuntime) cannot be run "
-                      "in a Flatpak environment. For Proton 5.13+, "
-                      "unofficial community builds that do not use "
-                      "pressure-vessel are available.");
-          goto out;
-        }
     }
   else
     {