Merge remote-tracking branch 'aosp/cuttlefish-testing' into master

Bug: 132289348
Test: TH
Change-Id: I5d87943cd32eeec7454d53807fd94082491b9d4d
diff --git a/Android.bp b/Android.bp
index a604f8c..624154c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -26,6 +26,13 @@
     host_supported: true,
 }
 
+cc_library_headers {
+    name: "cuttlefish_common_headers_product",
+    product_specific: true,
+    export_include_dirs: ["."],
+    host_supported: true,
+}
+
 // TODO(b/67435044) Update the include paths and remove this
 cc_library_headers {
     name: "cuttlefish_glog",
@@ -34,6 +41,14 @@
     host_supported: true,
 }
 
+// TODO(b/67435044) Update the include paths and remove this
+cc_library_headers {
+    name: "cuttlefish_glog_product",
+    product_specific: true,
+    export_include_dirs: ["common/libs"],
+    host_supported: true,
+}
+
 cc_defaults {
     name: "cuttlefish_base",
     gnu_extensions: false,
@@ -58,6 +73,29 @@
 }
 
 cc_defaults {
+    name: "cuttlefish_guest_product_only",
+    product_specific: true,
+    gnu_extensions: false,
+    header_libs: [
+        "cuttlefish_common_headers_product",
+        "cuttlefish_kernel_headers_product",
+        "cuttlefish_shared_config_product",
+    ],
+    target: {
+        host: {
+            host_ldlibs: ["-lrt"],
+            cflags: ["-DCUTTLEFISH_HOST"],
+            compile_multilib: "64",
+        },
+        // We don't need Darwin host-side builds
+        darwin: {
+            enabled: false,
+        },
+    },
+    cflags: ["-Werror", "-Wall"],
+}
+
+cc_defaults {
     name: "cuttlefish_guest_only",
     defaults: ["cuttlefish_base"],
 }
@@ -131,6 +169,7 @@
         "libbase",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_binary_host {
@@ -166,6 +205,7 @@
         "libgtest_host",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_test_host {
@@ -178,6 +218,7 @@
         "libbase",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_binary_host {
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..71249ba
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,16 @@
+{
+  "presubmit": [
+    {
+      "name": "circqueue_test",
+      "host": true
+    },
+    {
+      "name": "lock_test",
+      "host": true
+    },
+    {
+      "name": "vsoc_graphics_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/Android.bp b/common/libs/Android.bp
index 17a4c9d..e70e6ab 100644
--- a/common/libs/Android.bp
+++ b/common/libs/Android.bp
@@ -15,6 +15,7 @@
 
 subdirs = [
     "auto_resources",
+    "device_config",
     "fs",
     "net",
     "strings",
diff --git a/common/libs/auto_resources/Android.bp b/common/libs/auto_resources/Android.bp
index 2c575ce..482585e 100644
--- a/common/libs/auto_resources/Android.bp
+++ b/common/libs/auto_resources/Android.bp
@@ -21,6 +21,14 @@
     defaults: ["cuttlefish_host_and_guest"],
 }
 
+cc_library_static {
+    name: "cuttlefish_auto_resources_static",
+    srcs: [
+        "auto_resources.cpp",
+    ],
+    defaults: ["cuttlefish_guest_product_only"],
+}
+
 cc_test_host {
     name: "auto_free_buffer_test",
     srcs: [
@@ -33,4 +41,5 @@
         "libgmock",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/auto_resources/TEST_MAPPING b/common/libs/auto_resources/TEST_MAPPING
new file mode 100644
index 0000000..1e34e75
--- /dev/null
+++ b/common/libs/auto_resources/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "auto_free_buffer_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/constants/ril.h b/common/libs/constants/ril.h
deleted file mode 100644
index b9c3e8a..0000000
--- a/common/libs/constants/ril.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if defined(CUTTLEFISH_HOST)
-#define CF_PROPERTY_PREFIX "androidboot"
-#else
-#define CF_PROPERTY_PREFIX "ro.boot"
-#endif
-
-#define CUTTLEFISH_RIL_ADDR_PROPERTY CF_PROPERTY_PREFIX ".cuttlefish_ril_addr"
-#define CUTTLEFISH_RIL_GATEWAY_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_gateway"
-#define CUTTLEFISH_RIL_DNS_PROPERTY CF_PROPERTY_PREFIX ".cuttlefish_ril_dns"
-#define CUTTLEFISH_RIL_BROADCAST_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_broadcast"
-#define CUTTLEFISH_RIL_PREFIXLEN_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_prefixlen"
diff --git a/common/libs/device_config/Android.bp b/common/libs/device_config/Android.bp
new file mode 100644
index 0000000..36c8ddb
--- /dev/null
+++ b/common/libs/device_config/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libcuttlefish_device_config",
+    srcs: [
+        "device_config.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcuttlefish_fs",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_utils",
+    ],
+    target: {
+        host: {
+            srcs: [
+                "host_device_config.cpp",
+            ],
+            static_libs: [
+                "libcuttlefish_host_config",
+                "libjsoncpp",
+            ],
+        },
+        android: {
+            srcs: [
+                "guest_device_config.cpp",
+            ],
+            shared_libs: [
+                "libcutils",
+            ],
+        },
+    },
+    defaults: ["cuttlefish_host_and_guest"],
+}
diff --git a/common/libs/device_config/device_config.cpp b/common/libs/device_config/device_config.cpp
new file mode 100644
index 0000000..26bb9a1
--- /dev/null
+++ b/common/libs/device_config/device_config.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "device_config.h"
+
+#include <stdio.h>
+
+#include <sstream>
+#include <type_traits>
+
+#include <glog/logging.h>
+
+namespace cvd {
+
+// TODO(jemoreira): Endianness when on arm64 guest and x86 host is a problem
+// Raw data is sent through a vsocket from host to guest, this assert tries to
+// ensure the binary representation of the struct is the same in both sides.
+static_assert(sizeof(DeviceConfig::RawData) == 68 &&
+                  std::is_trivial<DeviceConfig::RawData>().value,
+              "DeviceConfigRawData needs to be the same in host and guess, did "
+              "you forget to update the size?");
+
+namespace {
+
+static constexpr auto kDataSize = sizeof(DeviceConfig::RawData);
+
+}  // namespace
+
+bool DeviceConfig::SendRawData(cvd::SharedFD fd) {
+  std::size_t sent = 0;
+  auto buffer = reinterpret_cast<uint8_t*>(&data_);
+  while (sent < kDataSize) {
+    auto bytes = fd->Write(buffer + sent, kDataSize - sent);
+    if (bytes < 0) {
+      // Don't log here, let the caller do it.
+      return false;
+    }
+    sent += bytes;
+  }
+  return true;
+}
+
+void DeviceConfig::generate_address_and_prefix() {
+  std::ostringstream ss;
+  ss << ril_ipaddr() << "/" << ril_prefixlen();
+  ril_address_and_prefix_ = ss.str();
+}
+
+}  // namespace cvd
\ No newline at end of file
diff --git a/common/libs/device_config/device_config.h b/common/libs/device_config/device_config.h
new file mode 100644
index 0000000..3fb2648
--- /dev/null
+++ b/common/libs/device_config/device_config.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <common/libs/fs/shared_fd.h>
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#ifdef CUTTLEFISH_HOST
+#include <host/libs/config/cuttlefish_config.h>
+#endif
+
+namespace cvd {
+
+class DeviceConfig {
+ public:
+  /**
+   * WARNING: Consider the possibility of different endianness between host and
+   * guest when adding fields of more than one byte to this struct:
+   * This struct is meant to be sent from host to guest so the binary
+   * representation must be the same. There is a static test that checks for
+   * alignment problems, but there is no such thing for endianness.
+   */
+  struct RawData {
+    struct {
+      char ipaddr[16];  // xxx.xxx.xxx.xxx\0 = 16 bytes
+      char gateway[16];
+      char dns[16];
+      char broadcast[16];
+      uint8_t prefixlen;
+      uint8_t reserved[3];
+    } ril;
+  };
+
+  static std::unique_ptr<DeviceConfig> Get();
+
+  bool SendRawData(cvd::SharedFD fd);
+
+  const char* ril_address_and_prefix() const {
+    return ril_address_and_prefix_.c_str();
+  };
+  const char* ril_ipaddr() const { return data_.ril.ipaddr; }
+  const char* ril_gateway() const { return data_.ril.gateway; }
+  const char* ril_dns() const { return data_.ril.dns; }
+  const char* ril_broadcast() const { return data_.ril.broadcast; }
+  int ril_prefixlen() const { return data_.ril.prefixlen; }
+
+ private:
+  void generate_address_and_prefix();
+#ifdef CUTTLEFISH_HOST
+  DeviceConfig() = default;
+  bool InitializeNetworkConfiguration(const vsoc::CuttlefishConfig& config);
+#else
+  explicit DeviceConfig(const RawData& data);
+#endif
+
+  RawData data_;
+  std::string ril_address_and_prefix_;
+};
+
+}  // namespace cvd
diff --git a/common/libs/device_config/guest_device_config.cpp b/common/libs/device_config/guest_device_config.cpp
new file mode 100644
index 0000000..90d2528
--- /dev/null
+++ b/common/libs/device_config/guest_device_config.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/properties.h>
+#include <glog/logging.h>
+
+#include "device_config.h"
+
+namespace cvd {
+
+namespace {
+
+static constexpr auto kDataSize = sizeof(DeviceConfig::RawData);
+
+bool GetRawFromServer(DeviceConfig::RawData* data) {
+  auto port_property = "ro.boot.cuttlefish_config_server_port";
+  auto port = property_get_int32(port_property, -1);
+  if (port < 0) {
+    LOG(ERROR) << "Unable to get config server port from property: " <<
+        port_property;
+    return false;
+  }
+  auto config_server =
+      cvd::SharedFD::VsockClient(2 /*host cid*/, port, SOCK_STREAM);
+  if (!config_server->IsOpen()) {
+    LOG(ERROR) << "Unable to connect to config server: "
+               << config_server->StrError();
+    return false;
+  }
+  uint8_t* buffer = reinterpret_cast<uint8_t*>(data);
+  size_t read_idx = 0;
+  while (read_idx < kDataSize) {
+    auto read = config_server->Read(buffer + read_idx, kDataSize - read_idx);
+    if (read == 0) {
+      LOG(ERROR) << "Unexpected EOF while reading from config server, read "
+                 << read_idx << " bytes, expected " << kDataSize;
+      return false;
+    }
+    if (read < 0) {
+      LOG(ERROR) << "Error reading from config server: "
+                 << config_server->StrError();
+      return false;
+    }
+    read_idx += read;
+  }
+  return true;
+}
+
+}  // namespace
+
+std::unique_ptr<DeviceConfig> DeviceConfig::Get() {
+  DeviceConfig::RawData data;
+  if (!GetRawFromServer(&data)) return nullptr;
+
+  return std::unique_ptr<DeviceConfig>(new DeviceConfig(data));
+}
+
+DeviceConfig::DeviceConfig(const DeviceConfig::RawData& data) : data_(data) {
+  generate_address_and_prefix();
+}
+
+}  // namespace cvd
diff --git a/host/commands/launch/ril_config.cc b/common/libs/device_config/host_device_config.cpp
similarity index 65%
rename from host/commands/launch/ril_config.cc
rename to common/libs/device_config/host_device_config.cpp
index 195256a..052e9bf 100644
--- a/host/commands/launch/ril_config.cc
+++ b/common/libs/device_config/host_device_config.cpp
@@ -15,23 +15,20 @@
  */
 
 #include <arpa/inet.h>
+#include <glog/logging.h>
 #include <ifaddrs.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/types.h>
 
-#include <memory>
-#include <sstream>
-#include <string>
+#include "device_config.h"
 
-#include <glog/logging.h>
-
-#include "common/libs/constants/ril.h"
-#include "host/commands/launch/ril_config.h"
+namespace cvd {
 
 namespace {
 
-int number_of_ones(unsigned long val) {
-  int ret = 0;
+uint8_t number_of_ones(unsigned long val) {
+  uint8_t ret = 0;
   while (val) {
     ret += val % 2;
     val >>= 1;
@@ -41,7 +38,7 @@
 
 class NetConfig {
  public:
-  uint32_t ril_prefixlen = -1;
+  uint8_t ril_prefixlen = -1;
   std::string ril_ipaddr;
   std::string ril_gateway;
   std::string ril_dns = "8.8.8.8";
@@ -54,16 +51,12 @@
     LOG(INFO) << "gateway = " << ril_gateway;
     LOG(INFO) << "dns = " << ril_dns;
     LOG(INFO) << "broadcast = " << ril_broadcast;
-    LOG(INFO) << "prefix length = " << ril_prefixlen;
+    LOG(INFO) << "prefix length = " << static_cast<int>(ril_prefixlen);
     return ret;
   }
 
  private:
   bool ParseIntefaceAttributes(struct ifaddrs* ifa) {
-    // if (ifa->ifa_addr->sa_family != AF_INET) {
-    //   LOG(ERROR) << "The " << ifa->ifa_name << " interface is not IPv4";
-    //   return false;
-    // }
     struct sockaddr_in* sa;
     char* addr_str;
 
@@ -122,30 +115,50 @@
   }
 };
 
-template <typename T>
-std::string BuildPropertyDefinition(const std::string& prop_name,
-                                  const T& prop_value) {
-  std::ostringstream stream;
-  stream << prop_name << "=" << prop_value;
-  return stream.str();
+inline void CopyChars(char* dest, size_t size, const char* src) {
+  auto res = snprintf(dest, size, "%s", src);
+  if (res >= static_cast<int>(size)) {
+    LOG(ERROR) << "Longer(" << res << ") than expected(" << (size - 1)
+               << ") config string was truncated: " << dest;
+  }
 }
+
 }  // namespace
 
-void ConfigureRil(vsoc::CuttlefishConfig* config) {
+std::unique_ptr<DeviceConfig> DeviceConfig::Get() {
+  auto config = vsoc::CuttlefishConfig::Get();
+  if (!config) return nullptr;
+  std::unique_ptr<DeviceConfig> dev_config(new DeviceConfig());
+  if (!dev_config->InitializeNetworkConfiguration(*config)) {
+    return nullptr;
+  }
+  return dev_config;
+}
+
+bool DeviceConfig::InitializeNetworkConfiguration(
+    const vsoc::CuttlefishConfig& config) {
   NetConfig netconfig;
-  if (!netconfig.ObtainConfig(config->mobile_bridge_name())) {
+  if (!netconfig.ObtainConfig(config.mobile_bridge_name())) {
     LOG(ERROR) << "Unable to obtain the network configuration";
-    return;
+    return false;
   }
 
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_ADDR_PROPERTY, netconfig.ril_ipaddr));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_GATEWAY_PROPERTY, netconfig.ril_gateway));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_DNS_PROPERTY, netconfig.ril_dns));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_BROADCAST_PROPERTY, netconfig.ril_broadcast));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_PREFIXLEN_PROPERTY, netconfig.ril_prefixlen));
+  auto res = snprintf(data_.ril.ipaddr, sizeof(data_.ril.ipaddr), "%s",
+                      netconfig.ril_ipaddr.c_str());
+  if (res >= (int)sizeof(data_.ril.ipaddr)) {
+    LOG(ERROR) << "Longer than expected config string was truncated: "
+               << data_.ril.ipaddr;
+  }
+  CopyChars(data_.ril.gateway, sizeof(data_.ril.gateway),
+            netconfig.ril_gateway.c_str());
+  CopyChars(data_.ril.dns, sizeof(data_.ril.dns), netconfig.ril_dns.c_str());
+  CopyChars(data_.ril.broadcast, sizeof(data_.ril.broadcast),
+            netconfig.ril_broadcast.c_str());
+  data_.ril.prefixlen = netconfig.ril_prefixlen;
+
+  generate_address_and_prefix();
+
+  return true;
 }
+
+}  // namespace cvd
diff --git a/common/libs/fs/Android.bp b/common/libs/fs/Android.bp
index 1522c50..9255b4f 100644
--- a/common/libs/fs/Android.bp
+++ b/common/libs/fs/Android.bp
@@ -26,3 +26,20 @@
     ],
     defaults: ["cuttlefish_host_and_guest"],
 }
+
+cc_library_static {
+    name: "libcuttlefish_fs_static",
+    static_libs: [
+        "cuttlefish_auto_resources_static",
+    ],
+    srcs: [
+        "gce_fs.cpp",
+        "shared_fd.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+    stl: "libc++_static",
+    defaults: ["cuttlefish_guest_product_only"],
+}
diff --git a/common/libs/net/Android.bp b/common/libs/net/Android.bp
index feb3b88..ea53f71 100644
--- a/common/libs/net/Android.bp
+++ b/common/libs/net/Android.bp
@@ -44,4 +44,5 @@
         "libgtest_host",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/net/TEST_MAPPING b/common/libs/net/TEST_MAPPING
new file mode 100644
index 0000000..a06d72a
--- /dev/null
+++ b/common/libs/net/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "cuttlefish_net_tests",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/time/Android.bp b/common/libs/time/Android.bp
index a390f68..972958f 100644
--- a/common/libs/time/Android.bp
+++ b/common/libs/time/Android.bp
@@ -30,4 +30,5 @@
         "cuttlefish_time",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/time/TEST_MAPPING b/common/libs/time/TEST_MAPPING
new file mode 100644
index 0000000..4c95014
--- /dev/null
+++ b/common/libs/time/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "monotonic_time_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp
index 773a56c..18dbbeb 100644
--- a/common/libs/utils/subprocess.cpp
+++ b/common/libs/utils/subprocess.cpp
@@ -188,6 +188,17 @@
   return retval;
 }
 
+Command::ParameterBuilder::~ParameterBuilder() {
+  Build();
+}
+void Command::ParameterBuilder::Build()  {
+  auto param = stream_.str();
+  stream_ = std::stringstream();
+  if (param.size()) {
+    cmd_->AddParameter(param);
+  }
+}
+
 Command::~Command() {
   // Close all inherited file descriptors
   for(const auto& entry: inherited_fds_) {
diff --git a/common/libs/utils/subprocess.h b/common/libs/utils/subprocess.h
index a7485c2..a299798 100644
--- a/common/libs/utils/subprocess.h
+++ b/common/libs/utils/subprocess.h
@@ -85,6 +85,24 @@
            BuildParameter(stream, args...);
   }
  public:
+  class ParameterBuilder {
+  public:
+    ParameterBuilder(Command* cmd) : cmd_(cmd) {};
+    ParameterBuilder(ParameterBuilder&& builder) = default;
+    ~ParameterBuilder();
+
+    template<typename T>
+    ParameterBuilder& operator<<(T t) {
+      cmd_->BuildParameter(&stream_, t);
+      return *this;
+    }
+
+    void Build();
+  private:
+    cvd::Command* cmd_;
+    std::stringstream stream_;
+  };
+
   Command(const std::string& executable) {
     command_.push_back(executable);
   }
@@ -117,6 +135,10 @@
     return false;
   }
 
+  ParameterBuilder GetParameterBuilder() {
+    return ParameterBuilder(this);
+  }
+
   // Redirects the standard IO of the command.
   bool RedirectStdIO(Subprocess::StdIOChannel channel, cvd::SharedFD shared_fd);
 
diff --git a/common/vsoc/lib/screen_region_view.h b/common/vsoc/lib/screen_region_view.h
index b439eea..aef4359 100644
--- a/common/vsoc/lib/screen_region_view.h
+++ b/common/vsoc/lib/screen_region_view.h
@@ -32,7 +32,8 @@
     : public vsoc::TypedRegionView<ScreenRegionView,
                                    vsoc::layout::screen::ScreenLayout> {
  public:
-  static int align(int input, int alignment = kAlignment) {
+  static int align(int input) {
+    auto constexpr alignment = 16;
     return (input + alignment - 1) & -alignment;
   }
 
@@ -95,7 +96,6 @@
   static constexpr int kGreenBits = 8;
   static constexpr int kBlueBits = 8;
   static constexpr uint32_t kFbPixelFormat = vsoc::VSOC_PIXEL_FORMAT_RGBA_8888;
-  static constexpr int kAlignment = 16;
 
  protected:
   const uint8_t* first_buffer() const;
diff --git a/guest/Android.bp b/guest/Android.bp
index ba07c2e..6b2406c 100644
--- a/guest/Android.bp
+++ b/guest/Android.bp
@@ -15,6 +15,7 @@
 
 subdirs = [
     "commands",
-    "hals/health",
-    "hals/hwcomposer",
+    "hals",
+    "monitoring",
+    "vsoc/lib",
 ]
diff --git a/guest/commands/Android.bp b/guest/commands/Android.bp
index 5c7c3c2..df15067 100644
--- a/guest/commands/Android.bp
+++ b/guest/commands/Android.bp
@@ -15,4 +15,8 @@
 
 subdirs = [
   "vsock_logcat",
+  "ip_link_add",
+  "usbforward",
+  "vport_trigger",
+  "vsoc_input_service",
 ]
diff --git a/guest/commands/ip_link_add/Android.bp b/guest/commands/ip_link_add/Android.bp
new file mode 100644
index 0000000..d84a5d1
--- /dev/null
+++ b/guest/commands/ip_link_add/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_binary {
+    name: "ip_link_add",
+    srcs: [
+        "main.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_net",
+        "cuttlefish_auto_resources",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/ip_link_add/Android.mk b/guest/commands/ip_link_add/Android.mk
deleted file mode 100644
index 993dea6..0000000
--- a/guest/commands/ip_link_add/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ip_link_add
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := cuttlefish_net cuttlefish_auto_resources
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/usbforward/Android.bp b/guest/commands/usbforward/Android.bp
new file mode 100644
index 0000000..a639567
--- /dev/null
+++ b/guest/commands/usbforward/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_binary {
+    name: "usbforward",
+    srcs: [
+        "main.cpp",
+        "usb_server.cpp",
+        "transport_request.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libusb",
+        "libbase",
+        "liblog",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"UsbForward\"",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/usbforward/Android.mk b/guest/commands/usbforward/Android.mk
deleted file mode 100644
index c8d219d..0000000
--- a/guest/commands/usbforward/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := usbforward
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    main.cpp \
-    usb_server.cpp \
-    transport_request.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_HEADER_LIBRARIES := \
-    libcutils_headers
-
-LOCAL_SHARED_LIBRARIES := \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libusb \
-    libbase \
-    liblog
-
-LOCAL_CFLAGS += -DLOG_TAG=\"UsbForward\"
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
diff --git a/guest/commands/usbforward/usb_server.cpp b/guest/commands/usbforward/usb_server.cpp
index 8c72137..e8f5525 100644
--- a/guest/commands/usbforward/usb_server.cpp
+++ b/guest/commands/usbforward/usb_server.cpp
@@ -276,7 +276,7 @@
 }
 
 int USBServer::HandleDeviceEvent(libusb_context*, libusb_device*,
-                                 libusb_hotplug_event event, void* self_raw) {
+                                 libusb_hotplug_event, void* self_raw) {
   auto self = reinterpret_cast<USBServer*>(self_raw);
   int64_t dummy = 1;
   self->device_event_fd_->Write(&dummy, sizeof(dummy));
diff --git a/guest/commands/vport_trigger/Android.bp b/guest/commands/vport_trigger/Android.bp
new file mode 100644
index 0000000..621b9c5
--- /dev/null
+++ b/guest/commands/vport_trigger/Android.bp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_binary {
+    name: "vport_trigger",
+    srcs: [
+        "main.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/vport_trigger/Android.mk b/guest/commands/vport_trigger/Android.mk
deleted file mode 100644
index e994ce9..0000000
--- a/guest/commands/vport_trigger/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := vport_trigger
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := libcutils
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/vsoc_input_service/Android.bp b/guest/commands/vsoc_input_service/Android.bp
new file mode 100644
index 0000000..76aae19
--- /dev/null
+++ b/guest/commands/vsoc_input_service/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_binary {
+    name: "vsoc_input_service",
+    srcs: [
+        "main.cpp",
+        "virtual_device_base.cpp",
+        "virtual_power_button.cpp",
+        "virtual_keyboard.cpp",
+        "virtual_touchscreen.cpp",
+        "vsoc_input_service.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+        "liblog",
+        "vsoc_lib",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/vsoc_input_service/Android.mk b/guest/commands/vsoc_input_service/Android.mk
deleted file mode 100644
index 2256ba5..0000000
--- a/guest/commands/vsoc_input_service/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_input_service
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    virtual_device_base.cpp \
-    virtual_power_button.cpp \
-    virtual_keyboard.cpp \
-    virtual_touchscreen.cpp \
-    vsoc_input_service.cpp \
-    main.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_SHARED_LIBRARIES := \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase \
-    liblog \
-    vsoc_lib
-
-LOCAL_CFLAGS += -DLOG_TAG=\"VSoCInputService\" \
-    -Wall -Werror
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/guest/hals/Android.bp b/guest/hals/Android.bp
new file mode 100644
index 0000000..6d01e72
--- /dev/null
+++ b/guest/hals/Android.bp
@@ -0,0 +1,20 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+subdirs = [
+    "gps",
+    "health",
+    "hwcomposer",
+]
diff --git a/guest/hals/gps/Android.bp b/guest/hals/gps/Android.bp
new file mode 100644
index 0000000..22c5998
--- /dev/null
+++ b/guest/hals/gps/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// HAL module implemenation, not prelinked and stored in
+// hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+cc_library_shared {
+    name: "gps.cutf",
+    relative_install_path: "hw",
+    srcs: [
+        "gps_vsoc.cpp",
+        "gps_thread.cpp",
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+    ],
+    header_libs: ["libhardware_headers"],
+    cflags: [
+        "-Wno-missing-field-initializers",
+        "-DLOG_TAG=\"VSoCGPS\"",
+    ],
+    defaults: ["cuttlefish_guest_only"],
+}
diff --git a/guest/hals/gps/Android.mk b/guest/hals/gps/Android.mk
deleted file mode 100644
index 9443980..0000000
--- a/guest/hals/gps/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation, not prelinked and stored in
-# hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?))
-LOCAL_MODULE_RELATIVE_PATH := hw
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-endif
-LOCAL_MULTILIB := first
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := gps_vsoc.cpp gps_thread.cpp
-LOCAL_MODULE := gps.cutf
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-
-LOCAL_HEADER_LIBRARIES := \
-    libhardware_headers
-
-LOCAL_CFLAGS := \
-    -Wall -Werror -Wno-missing-field-initializers \
-    -DLOG_TAG=\"VSoCGPS\" \
-    $(VSOC_VERSION_CFLAGS)
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/guest/hals/gralloc/legacy/Android.mk b/guest/hals/gralloc/legacy/Android.mk
index 57dae50..4bbc9c0 100644
--- a/guest/hals/gralloc/legacy/Android.mk
+++ b/guest/hals/gralloc/legacy/Android.mk
@@ -29,7 +29,7 @@
     $(VSOC_VERSION_CFLAGS)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := gralloc.cutf
+LOCAL_MODULE := gralloc.cutf_ashmem
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_TAGS := optional
 
diff --git a/guest/hals/gralloc/legacy/gralloc.cpp b/guest/hals/gralloc/legacy/gralloc.cpp
index 960b886..f890932 100644
--- a/guest/hals/gralloc/legacy/gralloc.cpp
+++ b/guest/hals/gralloc/legacy/gralloc.cpp
@@ -64,7 +64,7 @@
   // a gralloc buffer in this format.
   ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888);
   if (format == HAL_PIXEL_FORMAT_YV12) {
-    bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w, 16);
+    bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w);
   } else {
     bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w);
   }
diff --git a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
index 7f79002..16e2b33 100644
--- a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
+++ b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
@@ -285,9 +285,9 @@
 #ifdef GRALLOC_MODULE_API_VERSION_0_2
     case HAL_PIXEL_FORMAT_YCbCr_420_888:
 #endif
-      out->ystride = vsoc::screen::ScreenRegionView::align(width, 16);
+      out->ystride = vsoc::screen::ScreenRegionView::align(width);
       out->cstride =
-          vsoc::screen::ScreenRegionView::align(out->ystride / 2, 16);
+          vsoc::screen::ScreenRegionView::align(out->ystride / 2);
       out->chroma_step = 1;
       out->y = it;
       it += out->ystride * height;
@@ -331,8 +331,8 @@
     case HAL_PIXEL_FORMAT_RGB_888:
     case HAL_PIXEL_FORMAT_RGB_565:*/
     default:
-      w16 = vsoc::screen::ScreenRegionView::align(w, 16);
-      h16 = vsoc::screen::ScreenRegionView::align(h, 16);
+      w16 = vsoc::screen::ScreenRegionView::align(w);
+      h16 = vsoc::screen::ScreenRegionView::align(h);
       return bytes_per_pixel * w16 * h16 +
              vsoc::screen::ScreenRegionView::kSwiftShaderPadding;
   }
diff --git a/guest/hals/hwcomposer/common/hwcomposer.cpp b/guest/hals/hwcomposer/common/hwcomposer.cpp
index f18534b..56b2315 100644
--- a/guest/hals/hwcomposer/common/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/common/hwcomposer.cpp
@@ -44,9 +44,10 @@
   while (true) {
     struct timespec rt;
     if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
-      ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
-            strerror(errno));
+      LOG_ALWAYS_FATAL("%s:%d error in vsync thread clock_gettime: %s",
+        __FILE__, __LINE__, strerror(errno));
     }
+
     int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
     // Given now's timestamp calculate the time of the next timestamp.
     timestamp += pdev->vsync_period_ns -
diff --git a/guest/hals/hwcomposer/cutf_cvm/Android.bp b/guest/hals/hwcomposer/cutf_cvm/Android.bp
index 9e3962b..5a54d14 100644
--- a/guest/hals/hwcomposer/cutf_cvm/Android.bp
+++ b/guest/hals/hwcomposer/cutf_cvm/Android.bp
@@ -14,7 +14,7 @@
 
 
 cc_library_shared {
-    name: "hwcomposer.cutf_cvm",
+    name: "hwcomposer.cutf_cvm_ashmem",
     relative_install_path: "hw",
     defaults: ["cuttlefish_guest_only"],
     vendor: true,
@@ -30,6 +30,7 @@
     export_include_dirs: ["."],
     static_libs: ["libyuv_static", "hwcomposer_common"],
     shared_libs: [
+        "cuttlefish_auto_resources",
         "liblog",
         "libhardware",
         "libbase",
diff --git a/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp b/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp
index 23be7e1..a1f1597 100644
--- a/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp
+++ b/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp
@@ -77,30 +77,34 @@
 }
 
 FrameBuffer::FrameBuffer()
-    : screen_server_(cvd::SharedFD::VsockClient(
-          2, property_get_int32("ro.boot.vsock_frames_port", 5580),
-          SOCK_STREAM)),
-      broadcast_thread_([this]() { BroadcastLoop(); }) {
-  if (screen_server_->IsOpen()) {
-    // TODO(b/128842613): Get this info from the configuration server
-    int32_t screen_params[4];
-    auto res = screen_server_->Read(screen_params, sizeof(screen_params));
-    if (res == sizeof(screen_params)) {
-      x_res_ = screen_params[0];
-      y_res_ = screen_params[1];
-      dpi_ = screen_params[2];
-      refresh_rate_ = screen_params[3];
+    : broadcast_thread_([this]() { BroadcastLoop(); }) {
+  auto vsock_frames_port = property_get_int32("ro.boot.vsock_frames_port", -1);
+  if (vsock_frames_port > 0) {
+    screen_server_ = cvd::SharedFD::VsockClient(2, vsock_frames_port,
+                                                SOCK_STREAM);
+    if (screen_server_->IsOpen()) {
+      // TODO(b/128842613): Get this info from the configuration server
+      int32_t screen_params[4];
+      auto res = screen_server_->Read(screen_params, sizeof(screen_params));
+      if (res == sizeof(screen_params)) {
+        x_res_ = screen_params[0];
+        y_res_ = screen_params[1];
+        dpi_ = screen_params[2];
+        refresh_rate_ = screen_params[3];
+      } else {
+        LOG(ERROR) << "Unable to get screen configuration parameters from screen "
+                   << "server (" << res << "): " << screen_server_->StrError();
+      }
     } else {
-      LOG(ERROR) << "Unable to get screen configuration parameters from screen "
-                 << "server (" << res << "): " << screen_server_->StrError();
+      LOG(ERROR) << "Unable to connect to screen server: "
+                 << screen_server_->StrError();
     }
   } else {
-    LOG(ERROR) << "Unable to connect to screen server: "
-               << screen_server_->StrError();
+    LOG(INFO) << "No screen server configured, operating on headless mode";
   }
   // This needs to happen no matter what, otherwise there won't be a buffer for
   // the set calls to compose on.
-  inner_buffer_ = std::vector<char>(FrameBuffer::buffer_size() * 8);
+  inner_buffer_ = std::vector<char>(buffer_size() * 8);
 }
 
 FrameBuffer::~FrameBuffer() {
diff --git a/guest/hals/hwcomposer/vsoc/Android.mk b/guest/hals/hwcomposer/vsoc/Android.mk
index 2d22f2d..b7cb911 100644
--- a/guest/hals/hwcomposer/vsoc/Android.mk
+++ b/guest/hals/hwcomposer/vsoc/Android.mk
@@ -33,7 +33,7 @@
 # New hwcomposer, performs software composition
 include $(CLEAR_VARS)
 include $(LOCAL_PATH)/hwcomposer.mk
-LOCAL_MODULE := hwcomposer.cutf_ivsh
+LOCAL_MODULE := hwcomposer.cutf_ivsh_ashmem
 LOCAL_VENDOR_MODULE := true
 
 # See b/67109557
diff --git a/guest/hals/hwcomposer/vsoc/hwcomposer.cpp b/guest/hals/hwcomposer/vsoc/hwcomposer.cpp
index 16b63ba..2aaedd9 100644
--- a/guest/hals/hwcomposer/vsoc/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/vsoc/hwcomposer.cpp
@@ -440,8 +440,8 @@
   dev->vsync_data.vsync_period_ns = 1000000000 / refreshRate;
   struct timespec rt;
   if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
-    ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
-          strerror(errno));
+    LOG_ALWAYS_FATAL("%s:%d error in vsync thread clock_gettime: %s", __FILE__,
+      __LINE__, strerror(errno));
   }
   dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
 
diff --git a/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp b/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
index 33b08e1..d77c004 100644
--- a/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
+++ b/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
@@ -176,9 +176,9 @@
   uint8_t* src_y = src.buffer;
   int stride_y = stride_in_pixels;
   uint8_t* src_v = src_y + stride_y * src.height;
-  int stride_v = ScreenRegionView::align(stride_y / 2, 16);
+  int stride_v = ScreenRegionView::align(stride_y / 2);
   uint8_t* src_u = src_v + stride_v *  src.height / 2;
-  int stride_u = ScreenRegionView::align(stride_y / 2, 16);
+  int stride_u = ScreenRegionView::align(stride_y / 2);
 
   // Adjust for crop
   src_y += src.crop_y * stride_y + src.crop_x;
@@ -376,12 +376,12 @@
   int y_res = src_layer->displayFrame.bottom - src_layer->displayFrame.top;
   size_t output_frame_size =
       x_res *
-    ScreenRegionView::align(y_res * screen_view->bytes_per_pixel(), 16);
+    ScreenRegionView::align(y_res * screen_view->bytes_per_pixel());
   while (needed_tmp_buffers > 0) {
     BufferSpec tmp(RotateTmpBuffer(needed_tmp_buffers), output_frame_size,
                    x_res, y_res,
                    ScreenRegionView::align(
-                       x_res * screen_view->bytes_per_pixel(), 16));
+                       x_res * screen_view->bytes_per_pixel()));
     dest_buffer_stack.push_back(tmp);
     needed_tmp_buffers--;
   }
@@ -403,7 +403,7 @@
       int src_width = src_layer_spec.crop_width;
       int src_height = src_layer_spec.crop_height;
       int dst_stride = ScreenRegionView::align(
-          src_width * screen_view->bytes_per_pixel(), 16);
+          src_width * screen_view->bytes_per_pixel());
       size_t needed_size = dst_stride * src_height;
       dst_buffer_spec.width = src_width;
       dst_buffer_spec.height = src_height;
diff --git a/guest/hals/power/Android.mk b/guest/hals/power/Android.mk
deleted file mode 100644
index d73bc0f..0000000
--- a/guest/hals/power/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implementation stored in
-# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS += $(VSOC_VERSION_CFLAGS)
-
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?))
-LOCAL_MODULE_RELATIVE_PATH := hw
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-endif
-LOCAL_MULTILIB := first
-
-LOCAL_HEADER_LIBRARIES := libhardware_headers libutils_headers
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := power.c
-LOCAL_MODULE := power.cutf
-LOCAL_MODULE_TAGS := optional
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/guest/hals/power/power.c b/guest/hals/power/power.c
deleted file mode 100644
index 5bd3b0a..0000000
--- a/guest/hals/power/power.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Based on the HiKeyPowerHAL
- */
-
-#include <pthread.h>
-#include <semaphore.h>
-#include <cutils/properties.h>
-
-#define LOG_TAG "VSoCPowerHAL"
-#include <utils/Log.h>
-
-#include <hardware/hardware.h>
-#include <hardware/power.h>
-#include "guest/libs/platform_support/api_level_fixes.h"
-
-struct vsoc_power_module {
-    struct power_module base;
-    pthread_mutex_t lock;
-};
-
-
-#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
-
-static void vsoc_power_set_feature(struct power_module __unused *module,
-                                  feature_t __unused hint,
-                                  int __unused state) {
-    return;
-}
-
-#elif VSOC_PLATFORM_SDK_AFTER(L)
-
-static void vsoc_power_set_feature(struct power_module __unused *module,
-                                  power_hint_t __unused hint,
-                                  int __unused state) {
-    return;
-}
-
-#endif
-
-static void vsoc_power_hint(struct power_module __unused *module,
-                           power_hint_t __unused hint,
-                           void __unused *data) {
-    return;
-}
-
-static void vsoc_power_set_interactive(struct power_module __unused *module,
-                                      int __unused on) {
-    return;
-}
-
-static  void vsoc_power_init(struct power_module __unused *module) {
-    return;
-}
-
-
-/*
- * The power module wasn't opened at all in versions prior to 'O'. The module
- * pointer was reinterpretd as a device pointer. 'O' retains this behavior when
- * open is set to NULL. This code is using that mode.
- * For reference,
- * 'O': hardware/interfaces/power/1.0/default/Power.cpp
- * prior: frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
- */
-static struct hw_module_methods_t power_module_methods = {
-    VSOC_STATIC_INITIALIZER(open) NULL
-};
-
-
-struct vsoc_power_module HAL_MODULE_INFO_SYM = {
-  VSOC_STATIC_INITIALIZER(base) {
-    .common = {
-        VSOC_STATIC_INITIALIZER(tag) HARDWARE_MODULE_TAG,
-        VSOC_STATIC_INITIALIZER(module_api_version) POWER_MODULE_API_VERSION_0_2,
-        VSOC_STATIC_INITIALIZER(hal_api_version) HARDWARE_HAL_API_VERSION,
-        VSOC_STATIC_INITIALIZER(id) POWER_HARDWARE_MODULE_ID,
-        VSOC_STATIC_INITIALIZER(name) "VSoC Power HAL",
-        VSOC_STATIC_INITIALIZER(author) "The Android Open Source Project",
-        VSOC_STATIC_INITIALIZER(methods) &power_module_methods,
-    },
-    VSOC_STATIC_INITIALIZER(init) vsoc_power_init,
-    VSOC_STATIC_INITIALIZER(setInteractive) vsoc_power_set_interactive,
-    VSOC_STATIC_INITIALIZER(powerHint) vsoc_power_hint,
-    // Before L_MR1 we don't have setFeature
-#if VSOC_PLATFORM_SDK_AFTER(L)
-    VSOC_STATIC_INITIALIZER(setFeature) vsoc_power_set_feature,
-#endif
-  },
-
-  VSOC_STATIC_INITIALIZER(lock) PTHREAD_MUTEX_INITIALIZER,
-};
-
diff --git a/guest/hals/ril/Android.mk b/guest/hals/ril/Android.mk
index 0110fd2..77db038 100644
--- a/guest/hals/ril/Android.mk
+++ b/guest/hals/ril/Android.mk
@@ -28,6 +28,7 @@
   cuttlefish_net \
   cuttlefish_auto_resources \
   libbase \
+  libcuttlefish_device_config \
 
 LOCAL_C_INCLUDES := \
     device/google/cuttlefish_common \
diff --git a/guest/hals/ril/cuttlefish_ril.cpp b/guest/hals/ril/cuttlefish_ril.cpp
index 0acc452..209f3e8 100644
--- a/guest/hals/ril/cuttlefish_ril.cpp
+++ b/guest/hals/ril/cuttlefish_ril.cpp
@@ -27,7 +27,7 @@
 #include <string>
 #include <vector>
 
-#include "common/libs/constants/ril.h"
+#include "common/libs/device_config/device_config.h"
 #include "common/libs/net/netlink_client.h"
 #include "common/libs/net/network_interface.h"
 #include "common/libs/net/network_interface_manager.h"
@@ -62,48 +62,7 @@
   RUIM_NETWORK_PERSONALIZATION = 11
 } SIM_Status;
 
-class RilConfig {
- public:
-  static void InitRilConfig();
-
-  static char* address_and_prefixlength() {
-    return RilConfig::global_ril_config_.address_and_prefixlength_;
-  }
-
-  static char* dns() {
-    return RilConfig::global_ril_config_.dns_;
-  }
-
-  static char* gateway() {
-    return RilConfig::global_ril_config_.gateway_;
-  }
-
-  static char* ipaddr() {
-    return RilConfig::global_ril_config_.ipaddr_;
-  }
-
-  static int prefixlen() {
-    return RilConfig::global_ril_config_.prefixlen_;
-  }
-
-  static char* broadcast() {
-    return RilConfig::global_ril_config_.broadcast_;
-  }
-
- private:
-  RilConfig() = default;
-  RilConfig(const RilConfig&) = default;
-
-  char ipaddr_[16]; // xxx.xxx.xxx.xxx\0 = 16 bytes
-  char gateway_[16];
-  char dns_[16];
-  char broadcast_[16];
-  char address_and_prefixlength_[19]; // <ipaddr>/dd
-  int prefixlen_;
-
-  static RilConfig global_ril_config_;
-};
-RilConfig RilConfig::global_ril_config_;
+static std::unique_ptr<cvd::DeviceConfig> global_ril_config = nullptr;
 
 static const struct RIL_Env* gce_ril_env;
 
@@ -174,43 +133,6 @@
   return false;
 }
 
-static bool ReadStringProperty(char* dst, const char* key, size_t max_size) {
-  char buffer[PROPERTY_VALUE_MAX];
-  auto res = property_get(key, buffer, NULL);
-  if (res < 0) {
-    ALOGE("Failed to read property %s", key);
-    return false;
-  }
-  if (res > static_cast<int>(max_size - 1)) {
-    ALOGE("Invalid value in property %s: value too long: %s", key, buffer);
-    return false;
-  }
-  snprintf(dst, res + 1, "%s", buffer);
-  return true;
-}
-
-void RilConfig::InitRilConfig() {
-  RilConfig tmp_config;
-  ReadStringProperty(&tmp_config.ipaddr_[0], CUTTLEFISH_RIL_ADDR_PROPERTY,
-                     sizeof(tmp_config.ipaddr_));
-  ReadStringProperty(&tmp_config.gateway_[0],
-                     CUTTLEFISH_RIL_GATEWAY_PROPERTY,
-                     sizeof(tmp_config.gateway_));
-  ReadStringProperty(&tmp_config.dns_[0], CUTTLEFISH_RIL_DNS_PROPERTY,
-                     sizeof(tmp_config.dns_));
-  ReadStringProperty(&tmp_config.broadcast_[0],
-                     CUTTLEFISH_RIL_BROADCAST_PROPERTY,
-                     sizeof(tmp_config.broadcast_));
-  tmp_config.prefixlen_ =
-      property_get_int32(CUTTLEFISH_RIL_PREFIXLEN_PROPERTY, 30);
-
-  snprintf(&tmp_config.address_and_prefixlength_[0],
-           sizeof(tmp_config.address_and_prefixlength_), "%s/%d",
-           tmp_config.ipaddr_, tmp_config.prefixlen_);
-
-  RilConfig::global_ril_config_ = tmp_config;
-}
-
 // TearDownNetworkInterface disables network interface.
 // This call returns true, if operation was successful.
 bool TearDownNetworkInterface() {
@@ -270,9 +192,9 @@
 
     responses[index].ifname = (char*)"rmnet0";
     responses[index].addresses =
-      const_cast<char*>(RilConfig::address_and_prefixlength());
-    responses[index].dnses = RilConfig::dns();
-    responses[index].gateways = RilConfig::gateway();
+      const_cast<char*>(global_ril_config->ril_address_and_prefix());
+    responses[index].dnses = const_cast<char*>(global_ril_config->ril_dns());
+    responses[index].gateways = const_cast<char*>(global_ril_config->ril_gateway());
 #if VSOC_PLATFORM_SDK_AFTER(N_MR1)
     responses[index].pcscf = (char*)"";
     responses[index].mtu = 1440;
@@ -395,8 +317,9 @@
   }
 
   if (gDataCalls.empty()) {
-    SetUpNetworkInterface(RilConfig::ipaddr(), RilConfig::prefixlen(),
-                          RilConfig::broadcast());
+    SetUpNetworkInterface(global_ril_config->ril_ipaddr(),
+                          global_ril_config->ril_prefixlen(),
+                          global_ril_config->ril_broadcast());
   }
 
   gDataCalls[gNextDataCallId] = call;
@@ -2679,7 +2602,11 @@
   time(&gce_ril_start_time);
   gce_ril_env = env;
 
-  RilConfig::InitRilConfig();
+  global_ril_config = cvd::DeviceConfig::Get();
+  if (!global_ril_config) {
+    ALOGE("Failed to open device configuration!!!");
+    return nullptr;
+  }
 
   TearDownNetworkInterface();
 
diff --git a/guest/libs/wpa_supplicant_8_lib/Android.mk b/guest/libs/wpa_supplicant_8_lib/Android.mk
deleted file mode 100644
index 95b9662..0000000
--- a/guest/libs/wpa_supplicant_8_lib/Android.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
-
-ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
-  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
-endif
-
-# Use a custom libnl on releases before N
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -lt 24; echo $$?))
-EXTERNAL_VSOC_LIBNL_INCLUDE := external/gce/libnl/include
-else
-EXTERNAL_VSOC_LIBNL_INCLUDE :=
-endif
-
-
-WPA_SUPPL_DIR = external/wpa_supplicant_8
-WPA_SRC_FILE :=
-
-include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config
-
-WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
-	$(WPA_SUPPL_DIR)/src/common \
-	$(WPA_SUPPL_DIR)/src/drivers \
-	$(WPA_SUPPL_DIR)/src/l2_packet \
-	$(WPA_SUPPL_DIR)/src/utils \
-	$(WPA_SUPPL_DIR)/src/wps \
-	$(WPA_SUPPL_DIR)/wpa_supplicant \
-	$(EXTERNAL_VSOC_LIBNL_INCLUDE)
-
-WPA_SUPPL_DIR_INCLUDE += external/libnl/include
-
-ifdef CONFIG_DRIVER_NL80211
-WPA_SRC_FILE += driver_cmd_nl80211.c
-endif
-
-ifeq ($(TARGET_ARCH),arm)
-# To force sizeof(enum) = 4
-L_CFLAGS += -mabi=aapcs-linux
-endif
-
-ifdef CONFIG_ANDROID_LOG
-L_CFLAGS += -DCONFIG_ANDROID_LOG
-endif
-
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := lib_driver_cmd_simulated
-LOCAL_VENDOR_MODULE := true
-LOCAL_SHARED_LIBRARIES := libc libcutils
-
-LOCAL_CFLAGS := $(L_CFLAGS) \
-    $(VSOC_VERSION_CFLAGS)
-
-LOCAL_SRC_FILES := $(WPA_SRC_FILE)
-
-LOCAL_C_INCLUDES := \
-  device/google/cuttlefish_common \
-  $(WPA_SUPPL_DIR_INCLUDE)\
-
-include $(BUILD_STATIC_LIBRARY)
-
-########################
-
-endif
diff --git a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c
deleted file mode 100644
index a2180aa..0000000
--- a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Driver interaction with extended Linux CFG8021
- */
-
-#include "driver_cmd_nl80211.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if VSOC_PLATFORM_SDK_AFTER(L_MR1)
-// Android M exposes headers more directly.
-#include <netinet/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include "driver_nl80211.h"
-#elif VSOC_PLATFORM_SDK_AFTER(J_MR2)
-// Android versions K and L put structures in hardware_legacy
-#include "hardware_legacy/driver_nl80211.h"
-#else
-// Android version J does not expose structures directly. These structures are
-// manually defined later.
-#include <netinet/in.h>
-#include <linux/if.h>
-#endif
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "android_drv.h"
-
-
-int wpa_driver_nl80211_driver_cmd(
-    void* priv, char* cmd, char* buf, size_t buf_len) {
-  struct i802_bss* bss = priv;
-  struct wpa_driver_nl80211_data* drv = bss->drv;
-  struct ifreq ifr;
-  android_wifi_priv_cmd priv_cmd;
-  int ret = 0;
-
-  D("%s: called", __FUNCTION__);
-  if (os_strcasecmp(cmd, "STOP") == 0) {
-    linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
-  } else if (os_strcasecmp(cmd, "START") == 0) {
-    linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
-  } else if (os_strcasecmp(cmd, "MACADDR") == 0) {
-    u8 macaddr[ETH_ALEN] = {};
-
-    ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
-    if (!ret)
-      ret = os_snprintf(
-          buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
-  } else if (os_strcasecmp(cmd, "RELOAD") == 0) {
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
-  } else {  // Use private command
-    return 0;
-  }
-  return ret;
-}
-
-
-int wpa_driver_set_p2p_noa(void* priv, u8 count, int start, int duration) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
-
-
-int wpa_driver_get_p2p_noa(void* priv, u8* buf, size_t len) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
-
-
-int wpa_driver_set_p2p_ps(void* priv, int legacy_ps, int opp_ps, int ctwindow) {
-  D("%s: called", __FUNCTION__);
-  return -1;
-}
-
-
-int wpa_driver_set_ap_wps_p2p_ie(
-    void* priv, const struct wpabuf* beacon,
-    const struct wpabuf* proberesp, const struct wpabuf* assocresp) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
diff --git a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h b/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h
deleted file mode 100644
index 4256664..0000000
--- a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <guest/libs/platform_support/api_level_fixes.h>
-
-#include <memory.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "common.h"
-#include "linux_ioctl.h"
-#include "wpa_supplicant_i.h"
-#include <linux/if_ether.h>
-
-#define VSOC_WPA_SUPPLICANT_DEBUG 0
-
-#if VSOC_WPA_SUPPLICANT_DEBUG
-#  define D(...) ALOGD(__VA_ARGS__)
-#else
-#  define D(...) ((void)0)
-#endif
-
-
-typedef struct android_wifi_priv_cmd {
-  char* buf;
-  int used_len;
-  int total_len;
-} android_wifi_priv_cmd;
-
-#if VSOC_PLATFORM_SDK_BEFORE(K)
-
-#include "driver.h"
-
-struct i802_bss {
-  struct wpa_driver_nl80211_data* drv;
-  struct i802_bss* next;
-  int ifindex;
-  char ifname[IFNAMSIZ + 1];
-  char brname[IFNAMSIZ];
-
-  unsigned int beacon_set:1;
-  unsigned int added_if_into_bridge:1;
-  unsigned int added_bridge:1;
-  unsigned int in_deinit:1;
-
-  u8 addr[ETH_ALEN];
-
-  int freq;
-
-  void* ctx;
-  struct nl_handle* nl_preq;
-  struct nl_handle* nl_mgmt;
-  struct nl_cb* nl_cb;
-
-  struct nl80211_wiphy_data *wiphy_data;
-  struct dl_list wiphy_list;
-};
-
-struct nl80211_global {
-  struct dl_list interfaces;
-  int if_add_ifindex;
-  struct netlink_data *netlink;
-  struct nl_cb* nl_cb;
-  struct nl_handle* nl;
-  int nl80211_id;
-  int ioctl_sock;  // socket for ioctl() use
-
-  struct nl_handle* nl_event;
-};
-
-struct wpa_driver_nl80211_data {
-  struct nl80211_global* global;
-  struct dl_list list;
-  struct dl_list wiphy_list;
-  char phyname[32];
-  void* ctx;
-  int ifindex;
-  int if_removed;
-  int if_disabled;
-  int ignore_if_down_event;
-  struct rfkill_data* rfkill;
-  struct wpa_driver_capa capa;
-  u8* extended_capa;
-  u8* extended_capa_mask;
-  unsigned int extended_capa_len;
-  int has_capability;
-  // More internal data follows.
-};
-
-#endif  // VSOC_PLATFORM_SDK_AFTER(J)
diff --git a/guest/monitoring/Android.bp b/guest/monitoring/Android.bp
new file mode 100644
index 0000000..a7f69c0
--- /dev/null
+++ b/guest/monitoring/Android.bp
@@ -0,0 +1,19 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+subdirs = [
+    "dumpstate_ext",
+    "tombstone_transmit",
+]
diff --git a/guest/monitoring/vsoc_service/Android.mk b/guest/monitoring/cuttlefish_service/Android.mk
similarity index 95%
rename from guest/monitoring/vsoc_service/Android.mk
rename to guest/monitoring/cuttlefish_service/Android.mk
index 2f30405..d1baf7d 100644
--- a/guest/monitoring/vsoc_service/Android.mk
+++ b/guest/monitoring/cuttlefish_service/Android.mk
@@ -19,7 +19,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
 LOCAL_STATIC_JAVA_LIBRARIES := guava
-LOCAL_PACKAGE_NAME := VSoCService
+LOCAL_PACKAGE_NAME := CuttlefishService
 LOCAL_SDK_VERSION := 28
 LOCAL_PROGUARD_FLAGS := -include build/core/proguard.flags
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
diff --git a/guest/monitoring/vsoc_service/AndroidManifest.xml b/guest/monitoring/cuttlefish_service/AndroidManifest.xml
similarity index 100%
rename from guest/monitoring/vsoc_service/AndroidManifest.xml
rename to guest/monitoring/cuttlefish_service/AndroidManifest.xml
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BluetoothChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BootReporter.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BootReporter.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceFuture.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceFuture.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceService.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceService.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceWifiManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceWifiManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobBase.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobBase.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobExecutor.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobExecutor.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/LocationServicesManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/TombstoneChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
diff --git a/guest/monitoring/vsoc_service/proguard.flags b/guest/monitoring/cuttlefish_service/proguard.flags
similarity index 100%
rename from guest/monitoring/vsoc_service/proguard.flags
rename to guest/monitoring/cuttlefish_service/proguard.flags
diff --git a/guest/monitoring/dumpstate_ext/Android.bp b/guest/monitoring/dumpstate_ext/Android.bp
new file mode 100644
index 0000000..03f7b9f
--- /dev/null
+++ b/guest/monitoring/dumpstate_ext/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "android.hardware.dumpstate@1.0-service.cuttlefish",
+    srcs: [
+        "dumpstate_device.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.dumpstate@1.0",
+        "libbase",
+        "libcutils",
+        "libdumpstateutil",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"VSoC-dumpstate\"",
+    ],
+    relative_install_path: "hw",
+    init_rc: [
+        "android.hardware.dumpstate@1.0-service.cuttlefish.rc",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/monitoring/dumpstate_ext/Android.mk b/guest/monitoring/dumpstate_ext/Android.mk
deleted file mode 100644
index d425821..0000000
--- a/guest/monitoring/dumpstate_ext/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common
-LOCAL_CFLAGS := $(VSOC_VERSION_CFLAGS) -DLOG_TAG=\"VSoC-dumpstate\"
-LOCAL_SRC_FILES := dumpstate.cpp
-LOCAL_MODULE := libdumpstate.vsoc
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libdumpstateaidl \
-    libdumpstateutil \
-    libziparchive \
-    libz
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := android.hardware.dumpstate@1.0-service.cuttlefish
-LOCAL_INIT_RC := android.hardware.dumpstate@1.0-service.cuttlefish.rc
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
-    dumpstate_device.cpp \
-    service.cpp
-LOCAL_CFLAGS := $(VSOC_VERSION_CFLAGS) -DLOG_TAG=\"VSoC-dumpstate\"
-LOCAL_SHARED_LIBRARIES := \
-    android.hardware.dumpstate@1.0 \
-    libbase \
-    libcutils \
-    libdumpstateutil \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    liblog \
-    libutils
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    frameworks/native/cmds/dumpstate
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/guest/monitoring/dumpstate_ext/dumpstate.cpp b/guest/monitoring/dumpstate_ext/dumpstate.cpp
deleted file mode 100644
index 89e820b..0000000
--- a/guest/monitoring/dumpstate_ext/dumpstate.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "guest/libs/platform_support/api_level_fixes.h"
-
-#if VSOC_PLATFORM_SDK_BEFORE(N)
-extern "C" {
-#endif
-#include <dumpstate.h>
-#if VSOC_PLATFORM_SDK_BEFORE(N)
-}
-#endif
-
-void dumpstate_board() { Dumpstate& ds = Dumpstate::GetInstance(); };
diff --git a/guest/monitoring/tombstone_transmit/Android.bp b/guest/monitoring/tombstone_transmit/Android.bp
new file mode 100644
index 0000000..243877e
--- /dev/null
+++ b/guest/monitoring/tombstone_transmit/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "tombstone_transmit",
+    srcs: [
+        "main.cpp",
+    ],
+    static_libs: [
+        "libcuttlefish_fs_static",
+        "libgflags",
+        "cuttlefish_auto_resources_static",
+        "liblog",
+        "libbase",
+        "libcutils",
+    ],
+    stl: "libc++_static",
+    header_libs: [
+        "cuttlefish_glog_product",
+    ],
+    defaults: ["cuttlefish_guest_product_only"],
+}
diff --git a/guest/monitoring/tombstone_transmit/main.cpp b/guest/monitoring/tombstone_transmit/main.cpp
new file mode 100644
index 0000000..3633612
--- /dev/null
+++ b/guest/monitoring/tombstone_transmit/main.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <errno.h>
+#include <log/log.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/inotify.h>
+#include <unistd.h>
+#include <fstream>
+
+#include <cutils/properties.h>
+#include <gflags/gflags.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/utils/subprocess.h"
+
+static const char TOMBSTONE_DIR[] = "/data/tombstones/";
+
+// returns a fd which when read from, provides inotify events when tombstones
+// are created
+static int new_tombstone_create_notifier(void) {
+  int file_create_notification_handle = inotify_init();
+  if (file_create_notification_handle == -1) {
+    ALOGE("%s: inotify_init failure error: '%s' (%d)", __FUNCTION__,
+      strerror(errno), errno);
+    return -1;
+  }
+
+  int watch_descriptor = inotify_add_watch(file_create_notification_handle,
+    TOMBSTONE_DIR, IN_CREATE);
+  if (watch_descriptor == -1) {
+    ALOGE("%s: Could not add watch for '%s', error: '%s' (%d)", __FUNCTION__,
+      TOMBSTONE_DIR, strerror(errno), errno);
+    close(file_create_notification_handle);
+    return -1;
+  }
+
+  return file_create_notification_handle;
+}
+
+#define INOTIFY_MAX_EVENT_SIZE (sizeof(struct inotify_event) + NAME_MAX + 1)
+static std::string get_next_tombstone_path_blocking(int fd) {
+  char event_readout[INOTIFY_MAX_EVENT_SIZE];
+  struct inotify_event *i = (inotify_event*)(event_readout);
+
+  int event_read_out_length = read(fd, event_readout, INOTIFY_MAX_EVENT_SIZE);
+
+  if(event_read_out_length == -1) {
+    ALOGE("%s: Couldn't read out inotify event due to error: '%s' (%d)",
+      __FUNCTION__, strerror(errno), errno);
+    return std::string();
+  }
+
+  // Create event didn't show up for some reason or no file name was present
+  if(event_read_out_length == sizeof(struct inotify_event)) {
+    ALOGE("%s: inotify event didn't contain filename",__FUNCTION__);
+    return std::string();
+  }
+
+  if(!(i->mask & IN_CREATE)) {
+    ALOGE("%s: inotify event didn't pertain to file creation",__FUNCTION__);
+    return std::string();
+  }
+
+  std::string ret_value(TOMBSTONE_DIR);
+  return ret_value + i->name;
+}
+
+DEFINE_uint32(port, property_get_int32("ro.boot.vsock_tombstone_port", 0),
+              "VSOCK port to send tombstones to");
+DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to");
+#define TOMBSTONE_BUFFER_SIZE (1024)
+#define MAX_TOMBSTONE_SIZE (50 * TOMBSTONE_BUFFER_SIZE)
+
+int main(int argc, char** argv) {
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+  if(FLAGS_port == 0) {
+    LOG(FATAL_WITHOUT_ABORT) << "Port flag is required";
+    while(1) {sleep(1);};
+  }
+
+  int file_create_notification_handle = new_tombstone_create_notifier();
+  if (file_create_notification_handle == -1) {return -1;}
+
+  LOG(INFO) << "tombstone watcher successfully initialized";
+
+  while (true) {
+    std::string ts_path = get_next_tombstone_path_blocking(
+      file_create_notification_handle);
+
+    if(ts_path.empty()) {continue;}
+
+    auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port,
+      SOCK_STREAM);
+
+    std::ifstream ifs(ts_path);
+    char buffer[TOMBSTONE_BUFFER_SIZE];
+    uint num_transfers = 0;
+    int num_bytes_read = 0;
+    while (log_fd->IsOpen() && ifs.is_open() && !ifs.eof() &&
+           num_bytes_read < MAX_TOMBSTONE_SIZE) {
+      ifs.read(buffer, sizeof(buffer));
+      num_bytes_read += ifs.gcount();
+      log_fd->Write(buffer, ifs.gcount());
+      num_transfers++;
+    }
+
+    if (!log_fd->IsOpen()) {
+      ALOGE("Unable to connect to vsock:%u:%u: %s", FLAGS_cid, FLAGS_port,
+        log_fd->StrError());
+    } else if (!ifs.is_open()) {
+      ALOGE("%s closed in the middle of readout.", ts_path.c_str());
+    } else {
+      LOG(INFO) << num_bytes_read << " chars transferred from " <<
+        ts_path.c_str() << " over " << num_transfers << " "
+        << TOMBSTONE_BUFFER_SIZE << " byte sized transfers";
+    }
+  }
+
+  return 0;
+}
diff --git a/guest/vsoc/lib/Android.bp b/guest/vsoc/lib/Android.bp
new file mode 100644
index 0000000..d534a5d
--- /dev/null
+++ b/guest/vsoc/lib/Android.bp
@@ -0,0 +1,77 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "vsoc_driver_test",
+    srcs: [
+        "vsoc_driver_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
+
+cc_binary {
+    name: "vsoc_guest_region_e2e_test",
+    srcs: [
+        "guest_region_e2e_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
+
+cc_binary {
+    name: "vsoc_managed_region_e2e_test",
+    srcs: [
+        "managed_region_e2e_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/vsoc/lib/Android.mk b/guest/vsoc/lib/Android.mk
deleted file mode 100644
index 73240f4..0000000
--- a/guest/vsoc/lib/Android.mk
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_driver_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := vsoc_driver_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_guest_region_e2e_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := guest_region_e2e_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_managed_region_e2e_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := managed_region_e2e_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/host/commands/Android.bp b/host/commands/Android.bp
index c776291..89de143 100644
--- a/host/commands/Android.bp
+++ b/host/commands/Android.bp
@@ -21,4 +21,5 @@
     "record_audio",
     "virtual_usb_manager",
     "kernel_log_monitor",
+    "config_server",
 ]
diff --git a/host/commands/adbshell/main.cpp b/host/commands/adbshell/main.cpp
index 68ac18e..d893247 100644
--- a/host/commands/adbshell/main.cpp
+++ b/host/commands/adbshell/main.cpp
@@ -25,6 +25,8 @@
 #include <cstring>
 #include <string>
 #include <vector>
+
+#include <errno.h>
 #include <unistd.h>
 
 // Many of our users interact with CVDs via ssh. They expect to be able to
@@ -65,6 +67,14 @@
          "/cuttlefish_runtime/cuttlefish_config.json";
 }
 
+std::string CuttlefishFindAdb() {
+  std::string rval = std::string("/home/") + VsocUser() + "/bin/adb";
+  if (TEMP_FAILURE_RETRY(access(rval.c_str(), X_OK)) == -1) {
+    return "/usr/bin/adb";
+  }
+  return rval;
+}
+
 void SetCuttlefishConfigEnv() {
   setenv(vsoc::kCuttlefishConfigEnvVarName, CuttlefishConfigLocation().c_str(),
          true);
@@ -74,9 +84,10 @@
 int main(int argc, char* argv[]) {
   SetCuttlefishConfigEnv();
   auto instance = vsoc::CuttlefishConfig::Get()->adb_device_name();
+  std::string adb_path = CuttlefishFindAdb();
 
   std::vector<char*> new_argv = {
-      const_cast<char*>("/usr/bin/adb"), const_cast<char*>("-s"),
+      const_cast<char*>(adb_path.c_str()), const_cast<char*>("-s"),
       const_cast<char*>(instance.c_str()), const_cast<char*>("shell"),
       const_cast<char*>("/system/bin/sh")};
 
diff --git a/host/commands/config_server/Android.bp b/host/commands/config_server/Android.bp
new file mode 100644
index 0000000..07d832a
--- /dev/null
+++ b/host/commands/config_server/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary_host {
+    name: "config_server",
+    srcs: [
+        "main.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcuttlefish_fs",
+        "liblog",
+        "libcuttlefish_utils",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_device_config",
+    ],
+    static_libs: [
+        "libcuttlefish_host_config",
+        "libgflags",
+        "libjsoncpp",
+    ],
+    defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/commands/config_server/main.cpp b/host/commands/config_server/main.cpp
new file mode 100644
index 0000000..5970edf
--- /dev/null
+++ b/host/commands/config_server/main.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <common/libs/device_config/device_config.h>
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "host/libs/config/cuttlefish_config.h"
+
+DEFINE_int32(
+    server_fd, -1,
+    "File descriptor to an already created vsock server. If negative a new "
+    "server will be created at the port specified on the config file");
+
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv, android::base::StderrLogger);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  auto config = vsoc::CuttlefishConfig::Get();
+
+  cvd::SharedFD server_fd;
+  if (FLAGS_server_fd < 0) {
+    unsigned int port = config->config_server_port();
+    server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  } else {
+    server_fd = cvd::SharedFD::Dup(FLAGS_server_fd);
+    close(FLAGS_server_fd);
+  }
+
+  CHECK(server_fd->IsOpen()) << "Error creating or inheriting logcat server: "
+                             << server_fd->StrError();
+
+  auto device_config = cvd::DeviceConfig::Get();
+  if (!device_config) {
+    LOG(ERROR) << "Failed to obtain device configuration";
+    return -1;
+  }
+
+  // Server loop
+  while (true) {
+    auto conn = cvd::SharedFD::Accept(*server_fd);
+    LOG(INFO) << "Connection received on configuration server";
+
+    bool succeeded = device_config->SendRawData(conn);
+    if (succeeded) {
+      LOG(INFO) << "Successfully sent device configuration";
+    } else {
+      LOG(ERROR) << "Failed to send the device configuration: "
+                 << conn->StrError();
+    }
+  }
+}
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index 49672b1..b41cf77 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -18,7 +18,6 @@
     srcs: [
         "main.cc",
         "screen_region_handler.cc",
-        "ril_config.cc",
         "vsoc_shared_memory.cc",
         "boot_image_unpacker.cc",
         "process_monitor.cc",
diff --git a/host/commands/launch/flags.cc b/host/commands/launch/flags.cc
index 5ccf255..6c0867d 100644
--- a/host/commands/launch/flags.cc
+++ b/host/commands/launch/flags.cc
@@ -13,7 +13,6 @@
 #include "host/commands/launch/data_image.h"
 #include "host/commands/launch/launch.h"
 #include "host/commands/launch/launcher_defs.h"
-#include "host/commands/launch/ril_config.h"
 #include "host/libs/vm_manager/crosvm_manager.h"
 #include "host/libs/vm_manager/qemu_manager.h"
 #include "host/libs/vm_manager/vm_manager.h"
@@ -88,6 +87,12 @@
 DEFINE_string(
     vm_manager, vm_manager::CrosvmManager::name(),
     "What virtual machine manager to use, one of {qemu_cli, crosvm}");
+DEFINE_string(
+    gpu_mode, vsoc::kGpuModeGuestSwiftshader,
+    "What gpu configuration to use, one of {guest_swiftshader, drm_virgl}");
+DEFINE_string(wayland_socket, "",
+    "Location of the wayland socket to use for drm_virgl gpu_mode.");
+
 DEFINE_string(system_image_dir, vsoc::DefaultGuestImagePath(""),
               "Location of the system partition images.");
 DEFINE_string(vendor_image, "", "Location of the vendor partition image.");
@@ -188,8 +193,20 @@
                                "guest to host. One of [serial, vsock]");
 DEFINE_int32(logcat_vsock_port, vsoc::GetPerInstanceDefault(5620),
              "The port for logcat over vsock");
+DEFINE_string(config_server_binary,
+              vsoc::DefaultHostArtifactsPath("bin/config_server"),
+              "Binary for the configuration server");
+DEFINE_int32(config_server_port, vsoc::GetPerInstanceDefault(4680),
+             "The (vsock) port for the configuration server");
 DEFINE_int32(frames_vsock_port, vsoc::GetPerInstanceDefault(5580),
              "The vsock port to receive frames from the guest on");
+DEFINE_bool(enable_tombstone_receiver, false, "Enables the tombstone logger on "
+            "both the guest and the host");
+DEFINE_string(tombstone_receiver_binary,
+              vsoc::DefaultHostArtifactsPath("bin/tombstone_receiver"),
+              "Binary for the tombstone server");
+DEFINE_int32(tombstone_receiver_port, vsoc::GetPerInstanceDefault(5630),
+             "The vsock port for tombstones");
 namespace {
 
 template<typename S, typename T>
@@ -251,10 +268,18 @@
     LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
     return false;
   }
+  if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) {
+    LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
+    return false;
+  }
   tmp_config_obj.set_vm_manager(FLAGS_vm_manager);
-
-  // TODO(b/77276633): This should be handled as part of the GPU configuration
-  tmp_config_obj.add_kernel_cmdline("androidboot.hardware.egl=swiftshader");
+  tmp_config_obj.set_gpu_mode(FLAGS_gpu_mode);
+  if (!vm_manager::VmManager::ConfigureGpuMode(&tmp_config_obj)) {
+    LOG(ERROR) << "Invalid gpu_mode=" << FLAGS_gpu_mode <<
+               " does not work with vm_manager=" << FLAGS_vm_manager;
+    return false;
+  }
+  tmp_config_obj.set_wayland_socket(FLAGS_wayland_socket);
 
   vm_manager::VmManager::ConfigureBootDevices(&tmp_config_obj);
 
@@ -343,6 +368,8 @@
     tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_logcat_port=",
                                              FLAGS_logcat_vsock_port));
   }
+  tmp_config_obj.add_kernel_cmdline(concat("androidboot.cuttlefish_config_server_port=",
+                                           FLAGS_config_server_port));
   tmp_config_obj.set_hardware_name(FLAGS_hardware_name);
   if (!FLAGS_guest_security.empty()) {
     tmp_config_obj.add_kernel_cmdline(concat("security=", FLAGS_guest_security));
@@ -404,13 +431,13 @@
   tmp_config_obj.set_console_path(tmp_config_obj.PerInstancePath("console"));
   tmp_config_obj.set_logcat_path(tmp_config_obj.PerInstancePath("logcat"));
   tmp_config_obj.set_logcat_receiver_binary(FLAGS_logcat_receiver_binary);
+  tmp_config_obj.set_config_server_binary(FLAGS_config_server_binary);
   tmp_config_obj.set_launcher_log_path(tmp_config_obj.PerInstancePath("launcher.log"));
   tmp_config_obj.set_launcher_monitor_socket_path(
       tmp_config_obj.PerInstancePath("launcher_monitor.sock"));
 
   tmp_config_obj.set_mobile_bridge_name(FLAGS_mobile_interface);
   tmp_config_obj.set_mobile_tap_name(FLAGS_mobile_tap_name);
-  ConfigureRil(&tmp_config_obj);
 
   tmp_config_obj.set_wifi_tap_name(FLAGS_wifi_tap_name);
 
@@ -457,12 +484,26 @@
 
   tmp_config_obj.set_logcat_mode(FLAGS_logcat_mode);
   tmp_config_obj.set_logcat_vsock_port(FLAGS_logcat_vsock_port);
+  tmp_config_obj.set_config_server_port(FLAGS_config_server_port);
   tmp_config_obj.set_frames_vsock_port(FLAGS_frames_vsock_port);
-  if (!tmp_config_obj.enable_ivserver()) {
+  if (!tmp_config_obj.enable_ivserver() && tmp_config_obj.enable_vnc_server()) {
     tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_frames_port=",
                                              FLAGS_frames_vsock_port));
   }
 
+  tmp_config_obj.set_enable_tombstone_receiver(FLAGS_enable_tombstone_receiver);
+  tmp_config_obj.set_tombstone_receiver_port(FLAGS_tombstone_receiver_port);
+  tmp_config_obj.set_tombstone_receiver_binary(FLAGS_tombstone_receiver_binary);
+  if (FLAGS_enable_tombstone_receiver) {
+    tmp_config_obj.add_kernel_cmdline("androidboot.tombstone_transmit=1");
+    tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_tombstone_port="
+      ,FLAGS_tombstone_receiver_port));
+    // TODO (b/128842613) populate a cid flag to read the host CID during
+    // runtime
+  } else {
+    tmp_config_obj.add_kernel_cmdline("androidboot.tombstone_transmit=0");
+  }
+
   tmp_config_obj.set_cuttlefish_env_path(GetCuttlefishEnvPath());
 
   auto config_file = GetConfigFilePath(tmp_config_obj);
@@ -526,6 +567,11 @@
   SetCommandLineOptionWithMode("instance_dir",
                                default_instance_dir.c_str(),
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
+  auto default_wayland_socket = vsoc::DefaultEnvironmentPath(
+      "XDG_RUNTIME_DIR", default_instance_dir.c_str(), "wayland-0");
+  SetCommandLineOptionWithMode("wayland_socket",
+                               default_wayland_socket.c_str(),
+                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("hardware_name", "cutf_cvm",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("decompress_kernel", "true",
diff --git a/host/commands/launch/launch.cc b/host/commands/launch/launch.cc
index bc57025..7d8892d 100644
--- a/host/commands/launch/launch.cc
+++ b/host/commands/launch/launch.cc
@@ -3,6 +3,7 @@
 #include <glog/logging.h>
 
 #include "common/libs/fs/shared_fd.h"
+#include "common/libs/utils/files.h"
 #include "common/libs/utils/size_utils.h"
 #include "common/vsoc/shm/screen_layout.h"
 #include "host/commands/launch/launcher_defs.h"
@@ -131,32 +132,40 @@
   return ivserver;
 }
 
-// Build the kernel log monitor command. If boot_event_pipe is not NULL, a
-// subscription to boot events from the kernel log monitor will be created and
-// events will appear on *boot_events_pipe
-cvd::Command GetKernelLogMonitorCommand(const vsoc::CuttlefishConfig& config,
-                                        cvd::SharedFD* boot_events_pipe,
-                                        cvd::SharedFD* adbd_events_pipe) {
+std::vector<cvd::SharedFD> LaunchKernelLogMonitor(
+    const vsoc::CuttlefishConfig& config,
+    cvd::ProcessMonitor* process_monitor,
+    unsigned int number_of_event_pipes) {
   auto log_name = config.kernel_log_socket_name();
   auto server = cvd::SharedFD::SocketLocalServer(log_name.c_str(), false,
                                                  SOCK_STREAM, 0666);
-  cvd::Command kernel_log_monitor(config.kernel_log_monitor_binary());
-  kernel_log_monitor.AddParameter("-log_server_fd=", server);
+  cvd::Command command(config.kernel_log_monitor_binary());
+  command.AddParameter("-log_server_fd=", server);
 
-  cvd::SharedFD boot_pipe_write_end;
-  if (!cvd::SharedFD::Pipe(boot_events_pipe, &boot_pipe_write_end)) {
-    LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
-    std::exit(LauncherExitCodes::kPipeIOError);
-  }
-  cvd::SharedFD adbd_pipe_write_end;
-  if (!cvd::SharedFD::Pipe(adbd_events_pipe, &adbd_pipe_write_end)) {
-    LOG(ERROR) << "Unable to create adbd events pipe: " << strerror(errno);
-    std::exit(LauncherExitCodes::kPipeIOError);
-  }
-  kernel_log_monitor.AddParameter("-subscriber_fds=", boot_pipe_write_end, ",",
-                                  adbd_pipe_write_end);
+  std::vector<cvd::SharedFD> ret;
 
-  return kernel_log_monitor;
+  if (number_of_event_pipes > 0) {
+    auto param_builder = command.GetParameterBuilder();
+    param_builder << "-subscriber_fds=";
+    for (unsigned int i = 0; i < number_of_event_pipes; ++i) {
+      cvd::SharedFD event_pipe_write_end, event_pipe_read_end;
+      if (!cvd::SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) {
+        LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
+        std::exit(LauncherExitCodes::kPipeIOError);
+      }
+      if (i > 0) {
+        param_builder << ",";
+      }
+      param_builder << event_pipe_write_end;
+      ret.push_back(event_pipe_read_end);
+    }
+    param_builder.Build();
+  }
+
+  process_monitor->StartSubprocess(std::move(command),
+                                   GetOnSubprocessExitCallback(config));
+
+  return ret;
 }
 
 void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
@@ -177,6 +186,53 @@
                                    GetOnSubprocessExitCallback(config));
 }
 
+void LaunchConfigServer(const vsoc::CuttlefishConfig& config,
+                        cvd::ProcessMonitor* process_monitor) {
+  auto port = config.config_server_port();
+  auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  if (!socket->IsOpen()) {
+    LOG(ERROR) << "Unable to create configuration server socket: "
+               << socket->StrError();
+    std::exit(LauncherExitCodes::kConfigServerError);
+  }
+  cvd::Command cmd(config.config_server_binary());
+  cmd.AddParameter("-server_fd=", socket);
+  process_monitor->StartSubprocess(std::move(cmd),
+                                   GetOnSubprocessExitCallback(config));
+}
+
+void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
+                                      cvd::ProcessMonitor* process_monitor) {
+  if (!config.enable_tombstone_receiver()) {
+    return;
+  }
+
+  std::string tombstoneDir = config.PerInstancePath("tombstones");
+  if (!cvd::DirectoryExists(tombstoneDir.c_str())) {
+    LOG(INFO) << "Setting up " << tombstoneDir;
+    if (mkdir(tombstoneDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) <
+        0) {
+      LOG(ERROR) << "Failed to create tombstone directory: " << tombstoneDir
+                 << ". Error: " << errno;
+      exit(LauncherExitCodes::kTombstoneDirCreationError);
+    }
+  }
+
+  auto port = config.tombstone_receiver_port();
+  auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  if (!socket->IsOpen()) {
+    LOG(ERROR) << "Unable to create tombstone server socket: "
+               << socket->StrError();
+    std::exit(LauncherExitCodes::kTombstoneServerError);
+  }
+  cvd::Command cmd(config.tombstone_receiver_binary());
+  cmd.AddParameter("-server_fd=", socket);
+  cmd.AddParameter("-tombstone_dir=", tombstoneDir);
+
+  process_monitor->StartSubprocess(std::move(cmd),
+                                   GetOnSubprocessExitCallback(config));
+}
+
 void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor) {
   if (!AdbUsbEnabled(config)) {
@@ -206,7 +262,7 @@
   return server;
 }
 
-void LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
+bool LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor,
                               std::function<bool(MonitorEntry*)> callback) {
   if (config.enable_vnc_server()) {
@@ -220,14 +276,14 @@
       // crosvm)
       auto touch_server = CreateVncInputServer(config.touch_socket_path());
       if (!touch_server->IsOpen()) {
-        return;
+        return false;
       }
       vnc_server.AddParameter("-touch_fd=", touch_server);
 
       auto keyboard_server =
           CreateVncInputServer(config.keyboard_socket_path());
       if (!keyboard_server->IsOpen()) {
-        return;
+        return false;
       }
       vnc_server.AddParameter("-keyboard_fd=", keyboard_server);
       // TODO(b/128852363): This should be handled through the wayland mock
@@ -237,12 +293,14 @@
       auto frames_server =
           cvd::SharedFD::VsockServer(config.frames_vsock_port(), SOCK_STREAM);
       if (!frames_server->IsOpen()) {
-        return;
+        return false;
       }
       vnc_server.AddParameter("-frame_server_fd=", frames_server);
     }
     process_monitor->StartSubprocess(std::move(vnc_server), callback);
+    return true;
   }
+  return false;
 }
 
 void LaunchStreamAudioIfEnabled(const vsoc::CuttlefishConfig& config,
diff --git a/host/commands/launch/launch.h b/host/commands/launch/launch.h
index ae79de2..ec95c24 100644
--- a/host/commands/launch/launch.h
+++ b/host/commands/launch/launch.h
@@ -11,14 +11,17 @@
 void ValidateAdbModeFlag(const vsoc::CuttlefishConfig& config);
 
 cvd::Command GetIvServerCommand(const vsoc::CuttlefishConfig& config);
-cvd::Command GetKernelLogMonitorCommand(const vsoc::CuttlefishConfig& config,
-                                        cvd::SharedFD* boot_events_pipe,
-                                        cvd::SharedFD* adbd_events_pipe);
+std::vector <cvd::SharedFD> LaunchKernelLogMonitor(
+    const vsoc::CuttlefishConfig& config,
+    cvd::ProcessMonitor* process_monitor,
+    unsigned int number_of_event_pipes);
 void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
                                    cvd::ProcessMonitor* process_monitor);
+void LaunchConfigServer(const vsoc::CuttlefishConfig& config,
+                        cvd::ProcessMonitor* process_monitor);
 void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor);
-void LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
+bool LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor,
                               std::function<bool(cvd::MonitorEntry*)> callback);
 void LaunchStreamAudioIfEnabled(const vsoc::CuttlefishConfig& config,
@@ -33,3 +36,5 @@
                                  const vsoc::CuttlefishConfig& config);
 void LaunchIvServerIfEnabled(cvd::ProcessMonitor* process_monitor,
                              const vsoc::CuttlefishConfig& config);
+void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
+                                      cvd::ProcessMonitor* process_monitor);
\ No newline at end of file
diff --git a/host/commands/launch/launcher_defs.h b/host/commands/launch/launcher_defs.h
index 9a78a4e..2bca212 100644
--- a/host/commands/launch/launcher_defs.h
+++ b/host/commands/launch/launcher_defs.h
@@ -40,6 +40,9 @@
   kE2eTestFailed = 16,
   kKernelDecompressError = 17,
   kLogcatServerError = 18,
+  kConfigServerError = 19,
+  kTombstoneServerError = 20,
+  kTombstoneDirCreationError = 21,
 };
 
 // Actions supported by the launcher server
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index 9c0e3c3..5b05102 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -412,33 +412,40 @@
   // Monitor and restart host processes supporting the CVD
   cvd::ProcessMonitor process_monitor;
 
-  cvd::SharedFD boot_events_pipe;
-  cvd::SharedFD adbd_events_pipe;
-  // Only subscribe to boot events if running as daemon
-  process_monitor.StartSubprocess(
-      GetKernelLogMonitorCommand(*config, &boot_events_pipe, &adbd_events_pipe),
-      GetOnSubprocessExitCallback(*config));
+  auto event_pipes =
+      LaunchKernelLogMonitor(*config, &process_monitor, 2);
+  cvd::SharedFD boot_events_pipe = event_pipes[0];
+  cvd::SharedFD adbd_events_pipe = event_pipes[1];
+  event_pipes.clear();
 
   SetUpHandlingOfBootEvents(&process_monitor, boot_events_pipe,
                             boot_state_machine);
 
   LaunchLogcatReceiverIfEnabled(*config, &process_monitor);
 
+  LaunchConfigServer(*config, &process_monitor);
+
+  LaunchTombstoneReceiverIfEnabled(*config, &process_monitor);
+
   LaunchUsbServerIfEnabled(*config, &process_monitor);
 
   LaunchIvServerIfEnabled(&process_monitor, *config);
   // Launch the e2e tests after the ivserver is ready
   LaunchE2eTestIfEnabled(&process_monitor, boot_state_machine, *config);
 
+  // The vnc server needs to be launched after the ivserver because it connects
+  // to it when using qemu. It needs to launch before the VMM because it serves
+  // on several sockets (input devices, vsock frame server) when using crosvm.
+  auto frontend_enabled = LaunchVNCServerIfEnabled(
+      *config, &process_monitor, GetOnSubprocessExitCallback(*config));
+
   // Start the guest VM
-  process_monitor.StartSubprocess(vm_manager->StartCommand(),
+  process_monitor.StartSubprocess(vm_manager->StartCommand(frontend_enabled),
                                   GetOnSubprocessExitCallback(*config));
 
   // Start other host processes
   LaunchSocketForwardProxyIfEnabled(&process_monitor, *config);
   LaunchSocketVsockProxyIfEnabled(&process_monitor, *config);
-  LaunchVNCServerIfEnabled(*config, &process_monitor,
-                           GetOnSubprocessExitCallback(*config));
   LaunchStreamAudioIfEnabled(*config, &process_monitor,
                              GetOnSubprocessExitCallback(*config));
   LaunchAdbConnectorIfEnabled(&process_monitor, *config, adbd_events_pipe);
diff --git a/host/commands/launch/ril_config.h b/host/commands/launch/ril_config.h
deleted file mode 100644
index 49a43e8..0000000
--- a/host/commands/launch/ril_config.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "host/libs/config/cuttlefish_config.h"
-
-void ConfigureRil(vsoc::CuttlefishConfig* config);
\ No newline at end of file
diff --git a/host/commands/tombstone_receiver/Android.bp b/host/commands/tombstone_receiver/Android.bp
new file mode 100644
index 0000000..5f5a5a5
--- /dev/null
+++ b/host/commands/tombstone_receiver/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary_host {
+    name: "tombstone_receiver",
+    srcs: [
+        "main.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcuttlefish_fs",
+        "liblog",
+        "libcuttlefish_utils",
+        "cuttlefish_auto_resources",
+    ],
+    static_libs: [
+        "libcuttlefish_host_config",
+        "libgflags",
+        "libjsoncpp",
+    ],
+    defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/commands/tombstone_receiver/main.cpp b/host/commands/tombstone_receiver/main.cpp
new file mode 100644
index 0000000..7bea670
--- /dev/null
+++ b/host/commands/tombstone_receiver/main.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include <chrono>
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+
+#include "common/libs/fs/shared_fd.h"
+#include "host/libs/config/cuttlefish_config.h"
+
+DEFINE_int32(
+    server_fd, -1,
+    "File descriptor to an already created vsock server. If negative a new "
+    "server will be created at the port specified on the config file");
+DEFINE_string(tombstone_dir, "", "directory to write out tombstones in");
+
+static uint num_tombstones_in_last_second = 0;
+static std::string last_tombstone_name = "";
+
+static std::string next_tombstone_path() {
+  auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+  std::stringstream ss;
+  ss << FLAGS_tombstone_dir << "/tombstone_" <<
+    std::put_time(std::gmtime(&in_time_t), "%Y-%m-%d-%H%M%S");
+  auto retval = ss.str();
+
+  // Gives tombstones unique names
+  if(retval == last_tombstone_name) {
+    num_tombstones_in_last_second++;
+    retval += "_" + std::to_string(num_tombstones_in_last_second);
+  } else {
+    last_tombstone_name = retval;
+    num_tombstones_in_last_second = 0;
+  }
+
+  LOG(INFO) << "Creating " << retval;
+  return retval;
+}
+
+#define CHUNK_RECV_MAX_LEN (1024)
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv, android::base::StderrLogger);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  auto config = vsoc::CuttlefishConfig::Get();
+  cvd::SharedFD server_fd;
+
+  if (FLAGS_server_fd < 0) {
+    unsigned int port = config->tombstone_receiver_port();
+    server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  } else {
+    server_fd = cvd::SharedFD::Dup(FLAGS_server_fd);
+    close(FLAGS_server_fd);
+  }
+
+  CHECK(server_fd->IsOpen()) << "Error creating/inheriting tombstone server: "
+                             << server_fd->StrError();
+  LOG(INFO) << "Host is starting server on port "
+            << config->tombstone_receiver_port();
+
+  // Server loop
+  while (true) {
+    auto conn = cvd::SharedFD::Accept(*server_fd);
+    std::ofstream file(next_tombstone_path(),
+                       std::ofstream::out | std::ofstream::binary);
+
+    while (file.is_open()) {
+      char buff[CHUNK_RECV_MAX_LEN];
+      auto bytes_read = conn->Read(buff, sizeof(buff));
+      if (bytes_read <= 0) {
+        // reset the other side if it's still connected
+        break;
+      } else {
+        file.write(buff, bytes_read);
+      }
+    }
+  }
+
+  return 0;
+}
diff --git a/host/frontend/stream_audio/Android.bp b/host/frontend/stream_audio/Android.bp
index ab5ff8e..8f07536 100644
--- a/host/frontend/stream_audio/Android.bp
+++ b/host/frontend/stream_audio/Android.bp
@@ -33,5 +33,6 @@
         "libopuscpp",
     ],
     cpp_std: "c++17",
+    enabled: false,
     defaults: ["cuttlefish_host_only"],
 }
diff --git a/host/frontend/stream_audio/opuscpp/Android.bp b/host/frontend/stream_audio/opuscpp/Android.bp
index e0b97ac..9ad7a52 100644
--- a/host/frontend/stream_audio/opuscpp/Android.bp
+++ b/host/frontend/stream_audio/opuscpp/Android.bp
@@ -23,5 +23,6 @@
         "libopus",
     ],
     cpp_std: "c++17",
+    enabled: false,
     defaults: ["cuttlefish_host_only"],
 }
diff --git a/host/frontend/vnc_server/screen_connector.cpp b/host/frontend/vnc_server/screen_connector.cpp
index ea82f7e..1b9b900 100644
--- a/host/frontend/vnc_server/screen_connector.cpp
+++ b/host/frontend/vnc_server/screen_connector.cpp
@@ -61,6 +61,7 @@
     while (seq_num_ == *seq_num) {
       new_frame_cond_var_.wait(lock);
     }
+    *seq_num = seq_num_;
     return newest_buffer_;
   }
 
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 21ea347..55f0891 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -69,6 +69,8 @@
 const char* kSerialNumber = "serial_number";
 const char* kInstanceDir = "instance_dir";
 const char* kVmManager = "vm_manager";
+const char* const kGpuMode = "gpu_mode";
+const char* const kWaylandSocket = "wayland_socket";
 const char* kHardwareName = "hardware_name";
 const char* kDeviceTitle = "device_title";
 
@@ -157,12 +159,28 @@
 
 const char* kLogcatMode = "logcat_mode";
 const char* kLogcatVsockPort = "logcat_vsock_port";
+const char* kConfigServerPort = "config_server_port";
 const char* kFramesVsockPort = "frames_vsock_port";
 const char* kLogcatReceiverBinary = "logcat_receiver_binary";
+const char* kConfigServerBinary = "config_server_binary";
+
+const char* kRunTombstoneReceiver = "enable_tombstone_logger";
+const char* kTombstoneReceiverPort = "tombstone_logger_port";
+const char* kTombstoneReceiverBinary = "tombstone_receiver_binary";
 }  // namespace
 
 namespace vsoc {
 
+const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
+const char* const kGpuModeDrmVirgl = "drm_virgl";
+
+std::string DefaultEnvironmentPath(const char* environment_key,
+                                   const char* default_value,
+                                   const char* subpath) {
+  return cvd::StringFromEnv(environment_key, default_value) + "/" + subpath;
+}
+
+
 std::string CuttlefishConfig::instance_dir() const {
   return (*dictionary_)[kInstanceDir].asString();
 }
@@ -177,6 +195,21 @@
   (*dictionary_)[kVmManager] = name;
 }
 
+std::string CuttlefishConfig::gpu_mode() const {
+  return (*dictionary_)[kGpuMode].asString();
+}
+void CuttlefishConfig::set_gpu_mode(const std::string& name) {
+  (*dictionary_)[kGpuMode] = name;
+}
+
+std::string CuttlefishConfig::wayland_socket() const {
+  // Don't use SetPath here: the path is already fully formed.
+  return (*dictionary_)[kWaylandSocket].asString();
+}
+void CuttlefishConfig::set_wayland_socket(const std::string& path) {
+  (*dictionary_)[kWaylandSocket] = path;
+}
+
 std::string CuttlefishConfig::hardware_name() const {
   return (*dictionary_)[kHardwareName].asString();
 }
@@ -812,6 +845,14 @@
   return (*dictionary_)[kLogcatVsockPort].asInt();
 }
 
+void CuttlefishConfig::set_config_server_port(int port) {
+  (*dictionary_)[kConfigServerPort] = port;
+}
+
+int CuttlefishConfig::config_server_port() const {
+  return (*dictionary_)[kConfigServerPort].asInt();
+}
+
 void CuttlefishConfig::set_frames_vsock_port(int port) {
   (*dictionary_)[kFramesVsockPort] = port;
 }
@@ -828,6 +869,38 @@
   return (*dictionary_)[kLogcatReceiverBinary].asString();
 }
 
+void CuttlefishConfig::set_config_server_binary(const std::string& binary) {
+  SetPath(kConfigServerBinary, binary);
+}
+
+std::string CuttlefishConfig::config_server_binary() const {
+  return (*dictionary_)[kConfigServerBinary].asString();
+}
+
+bool CuttlefishConfig::enable_tombstone_receiver() const {
+  return (*dictionary_)[kRunTombstoneReceiver].asBool();
+}
+
+void CuttlefishConfig::set_enable_tombstone_receiver(bool enable_tombstone_receiver) {
+  (*dictionary_)[kRunTombstoneReceiver] = enable_tombstone_receiver;
+}
+
+std::string CuttlefishConfig::tombstone_receiver_binary() const {
+  return (*dictionary_)[kTombstoneReceiverBinary].asString();
+}
+
+void CuttlefishConfig::set_tombstone_receiver_binary(const std::string& e2e_test_binary) {
+  (*dictionary_)[kTombstoneReceiverBinary] = e2e_test_binary;
+}
+
+void CuttlefishConfig::set_tombstone_receiver_port(int port) {
+  (*dictionary_)[kTombstoneReceiverPort] = port;
+}
+
+int CuttlefishConfig::tombstone_receiver_port() const {
+  return (*dictionary_)[kTombstoneReceiverPort].asInt();
+}
+
 bool CuttlefishConfig::enable_ivserver() const {
   return hardware_name() == "cutf_ivsh";
 }
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index bc36540..4d495f0 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -57,6 +57,12 @@
   std::string vm_manager() const;
   void set_vm_manager(const std::string& name);
 
+  std::string gpu_mode() const;
+  void set_gpu_mode(const std::string& name);
+
+  std::string wayland_socket() const;
+  void set_wayland_socket(const std::string& path);
+
   std::string hardware_name() const;
   void set_hardware_name(const std::string& name);
 
@@ -187,6 +193,9 @@
   std::string logcat_receiver_binary() const;
   void set_logcat_receiver_binary(const std::string& binary);
 
+  std::string config_server_binary() const;
+  void set_config_server_binary(const std::string& binary);
+
   std::string launcher_log_path() const;
   void set_launcher_log_path(const std::string& launcher_log_path);
 
@@ -308,9 +317,21 @@
   void set_logcat_vsock_port(int port);
   int logcat_vsock_port() const;
 
+  void set_config_server_port(int port);
+  int config_server_port() const;
+
   void set_frames_vsock_port(int port);
   int frames_vsock_port() const;
 
+  void set_enable_tombstone_receiver(bool enable_tombstone_receiver);
+  bool enable_tombstone_receiver() const;
+
+  void set_tombstone_receiver_binary(const std::string& binary);
+  std::string tombstone_receiver_binary() const;
+
+  void set_tombstone_receiver_port(int port);
+  int tombstone_receiver_port() const;
+
   bool enable_ivserver() const;
 
   std::string touch_socket_path() const;
@@ -349,8 +370,15 @@
 
 std::string DefaultHostArtifactsPath(const std::string& file);
 std::string DefaultGuestImagePath(const std::string& file);
+std::string DefaultEnvironmentPath(const char* environment_key,
+                                   const char* default_value,
+                                   const char* path);
 
 // Whether the host supports qemu
 bool HostSupportsQemuCli();
 bool HostSupportsVsock();
+
+// GPU modes
+extern const char* const kGpuModeGuestSwiftshader;
+extern const char* const kGpuModeDrmVirgl;
 }  // namespace vsoc
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index a909b9b..4b2c444 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -53,6 +53,28 @@
 
 const std::string CrosvmManager::name() { return "crosvm"; }
 
+bool CrosvmManager::ConfigureGpu(vsoc::CuttlefishConfig* config) {
+  // Override the default HAL search paths in all cases. We do this because
+  // the HAL search path allows for fallbacks, and fallbacks in conjunction
+  // with properities lead to non-deterministic behavior while loading the
+  // HALs.
+  if (config->gpu_mode() == vsoc::kGpuModeDrmVirgl) {
+    config->add_kernel_cmdline("androidboot.hardware.gralloc=minigbm");
+    config->add_kernel_cmdline("androidboot.hardware.hwcomposer=drm_minigbm");
+    config->add_kernel_cmdline("androidboot.hardware.egl=mesa");
+    return true;
+  }
+  if (config->gpu_mode() == vsoc::kGpuModeGuestSwiftshader) {
+    config->add_kernel_cmdline(
+        "androidboot.hardware.gralloc=cutf_ashmem");
+    config->add_kernel_cmdline(
+        "androidboot.hardware.hwcomposer=cutf_cvm_ashmem");
+    config->add_kernel_cmdline("androidboot.hardware.egl=swiftshader");
+    return true;
+  }
+  return false;
+}
+
 void CrosvmManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
   // PCI domain 0, bus 0, device 5, function 0
   // TODO There is no way to control this assignment with crosvm (yet)
@@ -63,7 +85,7 @@
 CrosvmManager::CrosvmManager(const vsoc::CuttlefishConfig* config)
     : VmManager(config) {}
 
-cvd::Command CrosvmManager::StartCommand() {
+cvd::Command CrosvmManager::StartCommand(bool with_frontend) {
   // TODO Add aarch64 support
   // TODO Add the tap interfaces (--tap-fd)
   // TODO Redirect logcat output
@@ -75,6 +97,10 @@
   cvd::Command command(config_->crosvm_binary());
   command.AddParameter("run");
 
+  if (config_->gpu_mode() != vsoc::kGpuModeGuestSwiftshader) {
+    command.AddParameter("--gpu");
+    command.AddParameter("--wayland-sock=", config_->wayland_socket());
+  }
   if (!config_->ramdisk_image_path().empty()) {
     command.AddParameter("--initrd=", config_->ramdisk_image_path());
   }
@@ -98,9 +124,12 @@
   if (!config_->gsi_fstab_path().empty()) {
     command.AddParameter("--android-fstab=", config_->gsi_fstab_path());
   }
-  command.AddParameter("--single-touch=", config_->touch_socket_path(), ":",
-                       config_->x_res(), ":", config_->y_res());
-  command.AddParameter("--keyboard=", config_->keyboard_socket_path());
+
+  if (with_frontend) {
+    command.AddParameter("--single-touch=", config_->touch_socket_path(), ":",
+                         config_->x_res(), ":", config_->y_res());
+    command.AddParameter("--keyboard=", config_->keyboard_socket_path());
+  }
 
   AddTapFdParameter(&command, config_->wifi_tap_name());
   AddTapFdParameter(&command, config_->mobile_tap_name());
@@ -146,4 +175,3 @@
 }
 
 }  // namespace vm_manager
-
diff --git a/host/libs/vm_manager/crosvm_manager.h b/host/libs/vm_manager/crosvm_manager.h
index 112d781..4640cfa 100644
--- a/host/libs/vm_manager/crosvm_manager.h
+++ b/host/libs/vm_manager/crosvm_manager.h
@@ -28,12 +28,13 @@
  public:
   static const std::string name();
   static bool EnsureInstanceDirExists(const std::string& instance_dir);
+  static bool ConfigureGpu(vsoc::CuttlefishConfig* config);
   static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
 
   CrosvmManager(const vsoc::CuttlefishConfig* config);
   virtual ~CrosvmManager() = default;
 
-  cvd::Command StartCommand() override;
+  cvd::Command StartCommand(bool with_frontend) override;
   bool Stop() override;
 };
 
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index df78fc7..a9bb5cf 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -55,6 +55,22 @@
 
 const std::string QemuManager::name() { return "qemu_cli"; }
 
+bool QemuManager::ConfigureGpu(vsoc::CuttlefishConfig *config) {
+  if (config->gpu_mode() != vsoc::kGpuModeGuestSwiftshader) {
+    return false;
+  }
+  // Override the default HAL search paths in all cases. We do this because
+  // the HAL search path allows for fallbacks, and fallbacks in conjunction
+  // with properities lead to non-deterministic behavior while loading the
+  // HALs.
+  config->add_kernel_cmdline("androidboot.hardware.gralloc=cutf_ashmem");
+  config->add_kernel_cmdline(
+      "androidboot.hardware.hwcomposer=cutf_ivsh_ashmem");
+  config->add_kernel_cmdline(
+      "androidboot.hardware.egl=swiftshader");
+  return true;
+}
+
 void QemuManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
   // PCI domain 0, bus 0, device 3, function 0
   // This is controlled with 'addr=0x3' in cf_qemu.sh
@@ -65,7 +81,7 @@
 QemuManager::QemuManager(const vsoc::CuttlefishConfig* config)
   : VmManager(config) {}
 
-cvd::Command QemuManager::StartCommand(){
+cvd::Command QemuManager::StartCommand(bool /*with_frontend*/){
   // Set the config values in the environment
   LogAndSetEnv("qemu_binary", config_->qemu_binary());
   LogAndSetEnv("instance_name", config_->instance_name());
diff --git a/host/libs/vm_manager/qemu_manager.h b/host/libs/vm_manager/qemu_manager.h
index 4bcfe5a..66ff8d6 100644
--- a/host/libs/vm_manager/qemu_manager.h
+++ b/host/libs/vm_manager/qemu_manager.h
@@ -26,12 +26,13 @@
 class QemuManager : public VmManager {
  public:
   static const std::string name();
+  static bool ConfigureGpu(vsoc::CuttlefishConfig* config);
   static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
 
   QemuManager(const vsoc::CuttlefishConfig* config);
   virtual ~QemuManager() = default;
 
-  cvd::Command StartCommand() override;
+  cvd::Command StartCommand(bool with_frontend) override;
   bool Stop() override;
 };
 
diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp
index b3aef11..d613a56 100644
--- a/host/libs/vm_manager/vm_manager.cpp
+++ b/host/libs/vm_manager/vm_manager.cpp
@@ -48,6 +48,9 @@
             },
             []() { return vsoc::HostSupportsQemuCli(); },
             [](vsoc::CuttlefishConfig* c) {
+              return QemuManager::ConfigureGpu(c);
+            },
+            [](vsoc::CuttlefishConfig* c) {
               return QemuManager::ConfigureBootDevices(c);
             }
           },
@@ -61,6 +64,9 @@
             // Same as Qemu for the time being
             []() { return vsoc::HostSupportsQemuCli(); },
             [](vsoc::CuttlefishConfig* c) {
+              return CrosvmManager::ConfigureGpu(c);
+            },
+            [](vsoc::CuttlefishConfig* c) {
               return CrosvmManager::ConfigureBootDevices(c);
             }
           }
@@ -85,6 +91,14 @@
          vm_manager_helpers_[name].support_checker();
 }
 
+bool VmManager::ConfigureGpuMode(vsoc::CuttlefishConfig* config) {
+  auto it = vm_manager_helpers_.find(config->vm_manager());
+  if (it == vm_manager_helpers_.end()) {
+    return false;
+  }
+  return it->second.configure_gpu_mode(config);
+}
+
 void VmManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
   auto it = vm_manager_helpers_.find(config->vm_manager());
   if (it == vm_manager_helpers_.end()) {
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index 3073ab6..6b1661e 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -35,13 +35,14 @@
   static VmManager* Get(const std::string& vm_manager_name,
                         const vsoc::CuttlefishConfig* config);
   static bool IsValidName(const std::string& name);
+  static bool ConfigureGpuMode(vsoc::CuttlefishConfig* config);
   static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
   static bool IsVmManagerSupported(const std::string& name);
   static std::vector<std::string> GetValidNames();
 
   virtual ~VmManager() = default;
 
-  virtual cvd::Command StartCommand() = 0;
+  virtual cvd::Command StartCommand(bool with_frontend = true) = 0;
   virtual bool Stop() = 0;
 
   virtual bool ValidateHostConfiguration(
@@ -59,6 +60,7 @@
     std::function<VmManager*(const vsoc::CuttlefishConfig*)> builder;
     // Whether the host packages support this vm manager
     std::function<bool()> support_checker;
+    std::function<bool(vsoc::CuttlefishConfig*)> configure_gpu_mode;
     std::function<void(vsoc::CuttlefishConfig*)> configure_boot_devices;
   };
   // Asociates a vm manager helper to every valid vm manager name