Merge "Include Resize button that will scale the viewport"
diff --git a/common/frontend/socket_vsock_proxy/main.cpp b/common/frontend/socket_vsock_proxy/main.cpp
index 31cff0b..a9e295f 100644
--- a/common/frontend/socket_vsock_proxy/main.cpp
+++ b/common/frontend/socket_vsock_proxy/main.cpp
@@ -21,106 +21,15 @@
 
 #include "common/libs/fs/shared_fd.h"
 
-#ifdef CUTTLEFISH_HOST
-#include "host/libs/config/cuttlefish_config.h"
-#endif
-
-struct Header {
-  std::uint32_t payload_length;
-  enum MessageType : std::uint32_t {
-    DATA = 0,
-    BEGIN,
-    END,
-    RECV_CLOSED,  // indicate that this side's receive end is closed
-    RESTART,
-  };
-  MessageType message_type;
-};
-
 constexpr std::size_t kMaxPacketSize = 8192;
-constexpr std::size_t kMaxPayloadSize = kMaxPacketSize - sizeof(Header);
 
-struct Packet {
- private:
-  Header header_;
-  using Payload = char[kMaxPayloadSize];
-  Payload payload_data_;
-
-  static constexpr Packet MakePacket(Header::MessageType type) {
-    Packet packet{};
-    packet.header_.message_type = type;
-    return packet;
-  }
-
- public:
-  // port is only revelant on the host-side.
-  static Packet MakeBegin(std::uint16_t port);
-
-  static constexpr Packet MakeEnd() { return MakePacket(Header::END); }
-
-  static constexpr Packet MakeRecvClosed() {
-    return MakePacket(Header::RECV_CLOSED);
-  }
-
-  static constexpr Packet MakeRestart() { return MakePacket(Header::RESTART); }
-
-  // NOTE payload and payload_length must still be set.
-  static constexpr Packet MakeData() { return MakePacket(Header::DATA); }
-
-  bool empty() const { return IsData() && header_.payload_length == 0; }
-
-  void set_payload_length(std::uint32_t length) {
-    CHECK_LE(length, sizeof payload_data_);
-    header_.payload_length = length;
-  }
-
-  Payload& payload() { return payload_data_; }
-
-  const Payload& payload() const { return payload_data_; }
-
-  constexpr std::uint32_t payload_length() const {
-    return header_.payload_length;
-  }
-
-  constexpr bool IsBegin() const {
-    return header_.message_type == Header::BEGIN;
-  }
-
-  constexpr bool IsEnd() const { return header_.message_type == Header::END; }
-
-  constexpr bool IsData() const { return header_.message_type == Header::DATA; }
-
-  constexpr bool IsRecvClosed() const {
-    return header_.message_type == Header::RECV_CLOSED;
-  }
-
-  constexpr bool IsRestart() const {
-    return header_.message_type == Header::RESTART;
-  }
-
-  constexpr std::uint16_t port() const {
-    CHECK(IsBegin());
-    std::uint16_t port_number{};
-    CHECK_EQ(payload_length(), sizeof port_number);
-    std::memcpy(&port_number, payload(), sizeof port_number);
-    return port_number;
-  }
-
-  char* raw_data() { return reinterpret_cast<char*>(this); }
-
-  const char* raw_data() const { return reinterpret_cast<const char*>(this); }
-
-  constexpr size_t raw_data_length() const {
-    return payload_length() + sizeof header_;
-  }
-};
-
-static_assert(sizeof(Packet) == kMaxPacketSize, "");
-static_assert(std::is_pod<Packet>{}, "");
-
-DEFINE_uint32(tcp_port, 0, "TCP port (server on host, client on guest)");
-DEFINE_uint32(vsock_port, 0, "vsock port (client on host, server on guest");
-DEFINE_uint32(vsock_guest_cid, 0, "Guest identifier");
+DEFINE_string(server, "",
+              "The type of server to host, `vsock` or `tcp`. When hosting a server "
+              "of one type, the proxy will take inbound connections of this type and "
+              "make outbound connections of the other type.");
+DEFINE_uint32(tcp_port, 0, "TCP port");
+DEFINE_uint32(vsock_port, 0, "vsock port");
+DEFINE_uint32(vsock_cid, 0, "Vsock cid to initiate connections to");
 
 namespace {
 // Sends packets, Shutdown(SHUT_WR) on destruction
@@ -140,15 +49,15 @@
     }
   }
 
-  ssize_t SendAll(const Packet& packet) {
+  ssize_t SendAll(const std::vector<char>& packet) {
     ssize_t written{};
-    while (written < static_cast<ssize_t>(packet.payload_length())) {
+    while (written < static_cast<ssize_t>(packet.size())) {
       if (!socket_->IsOpen()) {
         return -1;
       }
       auto just_written =
-          socket_->Send(packet.payload() + written,
-                        packet.payload_length() - written, MSG_NOSIGNAL);
+          socket_->Send(packet.data() + written,
+                        packet.size() - written, MSG_NOSIGNAL);
       if (just_written <= 0) {
         LOG(INFO) << "Couldn't write to client: "
                   << strerror(socket_->GetErrno());
@@ -174,12 +83,12 @@
   SocketReceiver& operator=(const SocketReceiver&) = delete;
 
   // *packet will be empty if Read returns 0 or error
-  void Recv(Packet* packet) {
-    auto size = socket_->Read(packet->payload(), sizeof packet->payload());
+  void Recv(std::vector<char>* packet) {
+    auto size = socket_->Read(packet->data(), packet->size());
     if (size < 0) {
       size = 0;
     }
-    packet->set_payload_length(size);
+    packet->resize(size);
   }
 
  private:
@@ -189,7 +98,7 @@
 void SocketToVsock(SocketReceiver socket_receiver,
                    SocketSender vsock_sender) {
   while (true) {
-    auto packet = Packet::MakeData();
+    std::vector<char> packet(kMaxPacketSize, '\0');
     socket_receiver.Recv(&packet);
     if (packet.empty() || vsock_sender.SendAll(packet) < 0) {
       break;
@@ -200,10 +109,9 @@
 
 void VsockToSocket(SocketSender socket_sender,
                    SocketReceiver vsock_receiver) {
-  auto packet = Packet::MakeData();
+  std::vector<char> packet(kMaxPacketSize, '\0');
   while (true) {
     vsock_receiver.Recv(&packet);
-    CHECK(packet.IsData());
     if (packet.empty()) {
       break;
     }
@@ -224,9 +132,8 @@
   socket_to_vsock.join();
 }
 
-#ifdef CUTTLEFISH_HOST
-[[noreturn]] void host() {
-  LOG(INFO) << "starting server on " << FLAGS_tcp_port << " for vsock port "
+[[noreturn]] void TcpServer() {
+  LOG(INFO) << "starting TCP server on " << FLAGS_tcp_port << " for vsock port "
             << FLAGS_vsock_port;
   auto server = cvd::SharedFD::SocketLocalServer(FLAGS_tcp_port, SOCK_STREAM);
   CHECK(server->IsOpen()) << "Could not start server on " << FLAGS_tcp_port;
@@ -236,10 +143,10 @@
     auto client_socket = cvd::SharedFD::Accept(*server);
     CHECK(client_socket->IsOpen()) << "error creating client socket";
     cvd::SharedFD vsock_socket = cvd::SharedFD::VsockClient(
-        FLAGS_vsock_guest_cid, FLAGS_vsock_port, SOCK_STREAM);
+        FLAGS_vsock_cid, FLAGS_vsock_port, SOCK_STREAM);
     if (vsock_socket->IsOpen()) {
       last_failure_reason = 0;
-      LOG(INFO) << "Connected to vsock:" << FLAGS_vsock_guest_cid << ":"
+      LOG(INFO) << "Connected to vsock:" << FLAGS_vsock_cid << ":"
                 << FLAGS_vsock_port;
     } else {
       // Don't log if the previous connection failed with the same error
@@ -256,7 +163,6 @@
   }
 }
 
-#else
 cvd::SharedFD OpenSocketConnection() {
   while (true) {
     auto sock = cvd::SharedFD::SocketLocalClient(FLAGS_tcp_port, SOCK_STREAM);
@@ -280,9 +186,8 @@
   }
 }
 
-[[noreturn]] void guest() {
-  LOG(INFO) << "Starting guest mainloop";
-  LOG(INFO) << "starting server on " << FLAGS_vsock_port;
+[[noreturn]] void VsockServer() {
+  LOG(INFO) << "Starting vsock server on " << FLAGS_vsock_port;
   cvd::SharedFD vsock;
   do {
     vsock = cvd::SharedFD::VsockServer(FLAGS_vsock_port, SOCK_STREAM);
@@ -305,7 +210,6 @@
   }
 }
 
-#endif
 }  // namespace
 
 int main(int argc, char* argv[]) {
@@ -313,10 +217,12 @@
 
   CHECK(FLAGS_tcp_port != 0) << "Must specify -tcp_port flag";
   CHECK(FLAGS_vsock_port != 0) << "Must specify -vsock_port flag";
-#ifdef CUTTLEFISH_HOST
-  CHECK(FLAGS_vsock_guest_cid != 0) << "Must specify -vsock_guest_cid flag";
-  host();
-#else
-  guest();
-#endif
+  if (FLAGS_server == "tcp") {
+    CHECK(FLAGS_vsock_cid != 0) << "Must specify -vsock_cid flag";
+    TcpServer();
+  } else if (FLAGS_server == "vsock") {
+    VsockServer();
+  } else {
+    LOG(FATAL) << "Unknown server type: " << FLAGS_server;
+  }
 }
diff --git a/guest/hals/hwcomposer/common/hwcomposer.cpp b/guest/hals/hwcomposer/common/hwcomposer.cpp
index d86619d..c165f7e 100644
--- a/guest/hals/hwcomposer/common/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/common/hwcomposer.cpp
@@ -38,7 +38,9 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include <sstream>
 #include <string>
+#include <vector>
 
 #include <cutils/compiler.h>
 #include <cutils/properties.h>
@@ -76,6 +78,14 @@
   cvd::BaseComposer* composer;
 };
 
+struct external_display_config_t {
+  uint64_t physicalId;
+  uint32_t width;
+  uint32_t height;
+  uint32_t dpi;
+  uint32_t flags;
+};
+
 namespace {
 
 void* hwc_vsync_thread(void* data) {
@@ -275,21 +285,80 @@
   return true;
 }
 
+// Note predefined "hwservicemanager." is used to avoid adding new selinux rules
+#define EXTERANL_DISPLAY_PROP "hwservicemanager.external.displays"
+
+// return 0 for successful
+// return < 0 if failed
+int GetExternalDisplayConfigs(std::vector<struct external_display_config_t>* configs) {
+  // this guest property, hwservicemanager.external.displays,
+  // specifies multi-display info, with comma (,) as separator
+  // each display has the following info:
+  //   physicalId,width,height,dpi,flags
+  // several displays can be provided, e.g., following has 2 displays:
+  // setprop hwservicemanager.external.displays 1,1200,800,120,0,2,1200,800,120,0
+  std::vector<uint64_t> values;
+  char displays_value[PROPERTY_VALUE_MAX] = "";
+  property_get(EXTERANL_DISPLAY_PROP, displays_value, "");
+  bool valid = displays_value[0] != '\0';
+  if (valid) {
+      char *p = displays_value;
+      while (*p) {
+          if (!isdigit(*p) && *p != ',' && *p != ' ') {
+              valid = false;
+              break;
+          }
+          p++;
+      }
+  }
+  if (!valid) {
+      // no external displays are specified
+      ALOGE("%s: Invalid syntax for the value of system prop: %s, value: %s",
+          __FUNCTION__, EXTERANL_DISPLAY_PROP, displays_value);
+      return 0;
+  }
+  // parse all int values to a vector
+  std::istringstream stream(displays_value);
+  for (uint64_t id; stream >> id;) {
+      values.push_back(id);
+      if (stream.peek() == ',')
+          stream.ignore();
+  }
+  // each display has 5 values
+  if ((values.size() % 5) != 0) {
+      ALOGE("%s: Invalid value for system property: %s", __FUNCTION__, EXTERANL_DISPLAY_PROP);
+      return -1;
+  }
+  while (!values.empty()) {
+      struct external_display_config_t config;
+      config.physicalId = values[0];
+      config.width = values[1];
+      config.height = values[2];
+      config.dpi = values[3];
+      config.flags = values[4];
+      values.erase(values.begin(), values.begin() + 5);
+      configs->push_back(config);
+  }
+  return 0;
+}
+
 }  // namespace
 
 static int cvd_hwc_prepare(hwc_composer_device_1_t* dev, size_t numDisplays,
                            hwc_display_contents_1_t** displays) {
   if (!numDisplays || !displays) return 0;
 
-  hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
+  for (int disp = 0; disp < numDisplays; ++disp) {
+    hwc_display_contents_1_t* list = displays[disp];
 
-  if (!list) return 0;
-  if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
-    LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
-    return -1;
-  }
-  reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
+    if (!list) return 0;
+    if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
+      LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
+      return -1;
+    }
+    reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
       list->numHwLayers, &list->hwLayers[0]);
+  }
   return 0;
 }
 
@@ -297,38 +366,43 @@
                        hwc_display_contents_1_t** displays) {
   if (!numDisplays || !displays) return 0;
 
-  hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];
-  if (!contents) return 0;
+  int retval = -1;
+  for (int disp = 0; disp < numDisplays; ++disp) {
+    hwc_display_contents_1_t* contents = displays[disp];
+    if (!contents) return 0;
 
-  hwc_layer_1_t* layers = &contents->hwLayers[0];
-  if (contents->numHwLayers == 1 &&
+    hwc_layer_1_t* layers = &contents->hwLayers[0];
+    if (contents->numHwLayers == 1 &&
       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
-    ALOGW("Received request for empty composition, treating as valid noop");
-    return 0;
-  }
-  if (!IsValidComposition(contents->numHwLayers, layers, true)) {
-    LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
-    return -1;
-  }
-  int retval =
-      reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
-          contents->numHwLayers, layers);
-
-  int closedFds = 0;
-  for (size_t index = 0; index < contents->numHwLayers; ++index) {
-    if (layers[index].acquireFenceFd != -1) {
-      close(layers[index].acquireFenceFd);
-      layers[index].acquireFenceFd = -1;
-      ++closedFds;
+      ALOGW("Received request for empty composition, treating as valid noop");
+      return 0;
     }
-  }
-  if (closedFds) {
-    ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
+    if (!IsValidComposition(contents->numHwLayers, layers, true)) {
+      LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
+      return -1;
+    }
+    retval =
+        reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
+            contents->numHwLayers, layers);
+    if (retval != 0) break;
+
+    int closedFds = 0;
+    for (size_t index = 0; index < contents->numHwLayers; ++index) {
+      if (layers[index].acquireFenceFd != -1) {
+        close(layers[index].acquireFenceFd);
+        layers[index].acquireFenceFd = -1;
+        ++closedFds;
+      }
+    }
+    if (closedFds) {
+      ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
+    }
+
+    // TODO(ghartman): This should be set before returning. On the next set it
+    // should be signalled when we load the new frame.
+    contents->retireFenceFd = -1;
   }
 
-  // TODO(ghartman): This should be set before returning. On the next set it
-  // should be signalled when we load the new frame.
-  contents->retireFenceFd = -1;
   return retval;
 }
 
@@ -337,6 +411,14 @@
   struct cvd_hwc_composer_device_1_t* pdev =
       (struct cvd_hwc_composer_device_1_t*)dev;
   pdev->vsync_data.procs = procs;
+  if (procs) {
+      std::vector<struct external_display_config_t> configs;
+      int res = GetExternalDisplayConfigs(&configs);
+      if (res == 0 && !configs.empty()) {
+          // configs will be used in the future
+          procs->hotplug(procs, HWC_DISPLAY_EXTERNAL, 1);
+      }
+  }
 }
 
 static int cvd_hwc_query(hwc_composer_device_1_t* dev, int what, int* value) {
@@ -368,7 +450,7 @@
 }
 
 static int cvd_hwc_blank(hwc_composer_device_1_t* /*dev*/, int disp, int /*blank*/) {
-  if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL;
+  if (!IS_PRIMARY_DISPLAY(disp) && !IS_EXTERNAL_DISPLAY(disp)) return -EINVAL;
   return 0;
 }
 
@@ -381,7 +463,7 @@
                                        uint32_t* configs, size_t* numConfigs) {
   if (*numConfigs == 0) return 0;
 
-  if (IS_PRIMARY_DISPLAY(disp)) {
+  if (IS_PRIMARY_DISPLAY(disp) || IS_EXTERNAL_DISPLAY(disp)) {
     configs[0] = 0;
     *numConfigs = 1;
     return 0;
@@ -419,8 +501,7 @@
                                           int32_t* values) {
   struct cvd_hwc_composer_device_1_t* pdev =
       (struct cvd_hwc_composer_device_1_t*)dev;
-
-  if (!IS_PRIMARY_DISPLAY(disp)) {
+  if (!IS_PRIMARY_DISPLAY(disp) && !IS_EXTERNAL_DISPLAY(disp)) {
     ALOGE("unknown display type %u", disp);
     return -EINVAL;
   }
diff --git a/guest/hals/hwcomposer/common/hwcomposer.h b/guest/hals/hwcomposer/common/hwcomposer.h
index 0d91144..c7698b3 100644
--- a/guest/hals/hwcomposer/common/hwcomposer.h
+++ b/guest/hals/hwcomposer/common/hwcomposer.h
@@ -24,6 +24,7 @@
 
 #define IS_TARGET_FRAMEBUFFER(x) ((x) == HWC_FRAMEBUFFER_TARGET)
 #define IS_PRIMARY_DISPLAY(x) ((x) == HWC_DISPLAY_PRIMARY)
+#define IS_EXTERNAL_DISPLAY(x) ((x) == HWC_DISPLAY_EXTERNAL)
 
 namespace cvd {
 int cvd_hwc_open(std::unique_ptr<ScreenView> screen_view,
diff --git a/guest/hals/lights/Android.mk b/guest/hals/lights/Android.mk
deleted file mode 100644
index ce6d9e9..0000000
--- a/guest/hals/lights/Android.mk
+++ /dev/null
@@ -1,36 +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_C_INCLUDES := device/google/cuttlefish
-LOCAL_HEADER_LIBRARIES := libhardware_headers
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := lights_vsoc.c
-LOCAL_MODULE := lights.cutf
-LOCAL_CFLAGS += -DLIGHT_BACKLIGHT -DLOG_TAG=\"VSoC-lights\" $(VSOC_VERSION_CFLAGS)
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/guest/hals/lights/lights_vsoc.c b/guest/hals/lights/lights_vsoc.c
deleted file mode 100644
index 3cdb6c2..0000000
--- a/guest/hals/lights/lights_vsoc.c
+++ /dev/null
@@ -1,71 +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 <log/log.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <hardware/lights.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-static int set_light(struct light_device_t* dev,
-                     struct light_state_t const* state) {
-  ALOGI("%s: dev %p state %p", __FUNCTION__, dev, state);
-  if (state) {
-    ALOGI("%s: state value %d\n", __FUNCTION__, state->color);
-  }
-  return 0;
-}
-
-static int close_lights(struct light_device_t* dev) {
-  free(dev);
-  return 0;
-}
-
-static int open_lights(const struct hw_module_t* module,
-                       char const* name __unused, struct hw_device_t** device) {
-  struct light_device_t* dev = malloc(sizeof(struct light_device_t));
-  if (dev == NULL) {
-    return -EINVAL;
-  }
-  memset(dev, 0, sizeof(*dev));
-
-  dev->common.tag = HARDWARE_DEVICE_TAG;
-  dev->common.version = 0;
-  dev->common.module = (struct hw_module_t*)module;
-  dev->common.close = (int (*)(struct hw_device_t*))close_lights;
-  dev->set_light = set_light;
-  *device = (struct hw_device_t*)dev;
-  return 0;
-}
-
-static struct hw_module_methods_t lights_module_methods = {
-    .open = open_lights,
-};
-
-struct hw_module_t HAL_MODULE_INFO_SYM = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 1,
-    .version_minor = 0,
-    .id = LIGHTS_HARDWARE_MODULE_ID,
-    .name = "Android GCE lights Module",
-    .author = "Google",
-    .methods = & lights_module_methods,
-};
diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp b/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
index 48bc9d2..ca7d9b7 100644
--- a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
+++ b/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
@@ -16,8 +16,11 @@
 #include "guest/monitoring/dumpstate_ext/dumpstate_device.h"
 
 #include <DumpstateUtil.h>
+#include <android-base/properties.h>
 #include <log/log.h>
 
+#define DEVICE_LOGGING_PROPERTY "persist.vendor.logging_enabled"
+
 using android::os::dumpstate::DumpFileToFd;
 
 namespace android {
@@ -28,37 +31,63 @@
 
 // Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
 Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) {
-  return dumpstateBoard_1_1(handle, DumpstateMode::DEFAULT, 30 * 1000 /* timeoutMillis */);
+  // Ignore return value, just return an empty status.
+  dumpstateBoard_1_1(handle, DumpstateMode::DEFAULT, 30 * 1000 /* timeoutMillis */);
+  return Void();
 }
 
 // Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
-Return<void> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& handle,
-                                                 DumpstateMode mode,
-                                                 uint64_t /* timeoutMillis */) {
+Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& handle,
+                                                            DumpstateMode mode,
+                                                            uint64_t /* timeoutMillis */) {
   if (handle == nullptr || handle->numFds < 1) {
-    ALOGE("no FDs\n");
-    return Void();
+    ALOGE("No FDs\n");
+    return DumpstateStatus::ILLEGAL_ARGUMENT;
   }
 
   int fd = handle->data[0];
   if (fd < 0) {
-    ALOGE("invalid FD: %d\n", handle->data[0]);
-    return Void();
+    ALOGE("Invalid FD: %d\n", fd);
+    return DumpstateStatus::ILLEGAL_ARGUMENT;
   }
 
-  if (mode < DumpstateMode::FULL || mode > DumpstateMode::DEFAULT) {
+  bool isModeValid = false;
+  for (const auto dumpstateMode : hidl_enum_range<DumpstateMode>()) {
+    isModeValid |= (dumpstateMode == mode);
+  }
+  if (!isModeValid) {
     ALOGE("Invalid mode: %d\n", mode);
-    return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+    return DumpstateStatus::ILLEGAL_ARGUMENT;
+  }
+
+  if (mode == DumpstateMode::WEAR) {
+    // We aren't a Wear device. Mostly just for variety in our return values for testing purposes.
+    ALOGE("Unsupported mode: %d\n", mode);
+    return DumpstateStatus::UNSUPPORTED_MODE;
+  }
+
+  if (mode == DumpstateMode::PROTO) {
+    // We don't support dumping a protobuf yet.
+    ALOGE("Unsupported mode: %d\n", mode);
+    return DumpstateStatus::UNSUPPORTED_MODE;
+  }
+
+  if (!::android::base::GetBoolProperty(DEVICE_LOGGING_PROPERTY, false)) {
+    return DumpstateStatus::DEVICE_LOGGING_NOT_ENABLED;
   }
 
   DumpFileToFd(fd, "GCE INITIAL METADATA", "/initial.metadata");
 
+  return DumpstateStatus::OK;
+}
+
+Return<void> DumpstateDevice::setDeviceLoggingEnabled(bool enable) {
+  ::android::base::SetProperty(DEVICE_LOGGING_PROPERTY, enable ? "true" : "false");
   return Void();
 }
 
-Return<bool> DumpstateDevice::setDeviceLoggingEnabled(bool /* enable */) {
-  // Unsupported operation.
-  return false;
+Return<bool> DumpstateDevice::getDeviceLoggingEnabled() {
+  return ::android::base::GetBoolProperty(DEVICE_LOGGING_PROPERTY, false);
 }
 
 }  // namespace implementation
diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.h b/guest/monitoring/dumpstate_ext/dumpstate_device.h
index 2f6990d..4b97d84 100644
--- a/guest/monitoring/dumpstate_ext/dumpstate_device.h
+++ b/guest/monitoring/dumpstate_ext/dumpstate_device.h
@@ -26,24 +26,27 @@
 namespace V1_1 {
 namespace implementation {
 
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::dumpstate::V1_1::DumpstateMode;
-using ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
+using ::android::sp;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
-using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::dumpstate::V1_1::DumpstateMode;
+using ::android::hardware::dumpstate::V1_1::DumpstateStatus;
+using ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
 
 struct DumpstateDevice : public IDumpstateDevice {
   // Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
   Return<void> dumpstateBoard(const hidl_handle& h) override;
 
   // Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
-  Return<void> dumpstateBoard_1_1(const hidl_handle& h, DumpstateMode mode,
-                                  uint64_t timeoutMillis) override;
-  Return<bool> setDeviceLoggingEnabled(bool enable) override;
+  Return<DumpstateStatus> dumpstateBoard_1_1(const hidl_handle& h,
+                                             DumpstateMode mode,
+                                             uint64_t timeoutMillis) override;
+  Return<void> setDeviceLoggingEnabled(bool enable) override;
+  Return<bool> getDeviceLoggingEnabled() override;
 };
 
 }  // namespace implementation
diff --git a/host/commands/fetcher/build_api.cc b/host/commands/fetcher/build_api.cc
index fb685c7..1f3d81b 100644
--- a/host/commands/fetcher/build_api.cc
+++ b/host/commands/fetcher/build_api.cc
@@ -175,7 +175,7 @@
 Build ArgumentToBuild(BuildApi* build_api, const std::string& arg,
                       const std::string& default_build_target,
                       const std::chrono::seconds& retry_period) {
-  if (arg.find(":") != std::string::npos) {
+  if (arg.find(':') != std::string::npos) {
     std::vector<std::string> dirs = android::base::Split(arg, ":");
     std::string id = dirs.back();
     dirs.pop_back();
diff --git a/host/commands/fetcher/fetch_cvd.cc b/host/commands/fetcher/fetch_cvd.cc
index 308a1bb..8a15686 100644
--- a/host/commands/fetcher/fetch_cvd.cc
+++ b/host/commands/fetcher/fetch_cvd.cc
@@ -73,7 +73,7 @@
     const Build& build, const std::string& name,
     const std::vector<Artifact>& artifacts) {
   std::string target = std::visit([](auto&& arg) { return arg.target; }, build);
-  size_t dash_pos = target.find("-");
+  size_t dash_pos = target.find('-');
   if (dash_pos != std::string::npos) {
     target.replace(dash_pos, target.size() - dash_pos, "");
   }
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index dc2e108..e34303b 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -319,20 +319,22 @@
   auto instance = config.ForDefaultInstance();
   if (AdbVsockTunnelEnabled(config)) {
     cvd::Command adb_tunnel(config.socket_vsock_proxy_binary());
+    adb_tunnel.AddParameter("--server=tcp");
     adb_tunnel.AddParameter("--vsock_port=6520");
     adb_tunnel.AddParameter(
         std::string{"--tcp_port="} + std::to_string(instance.host_port()));
-    adb_tunnel.AddParameter(std::string{"--vsock_guest_cid="} +
+    adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
                             std::to_string(instance.vsock_guest_cid()));
     process_monitor->StartSubprocess(std::move(adb_tunnel),
                                      GetOnSubprocessExitCallback(config));
   }
   if (AdbVsockHalfTunnelEnabled(config)) {
     cvd::Command adb_tunnel(config.socket_vsock_proxy_binary());
+    adb_tunnel.AddParameter("--server=tcp");
     adb_tunnel.AddParameter("--vsock_port=5555");
     adb_tunnel.AddParameter(
         std::string{"--tcp_port="} + std::to_string(instance.host_port()));
-    adb_tunnel.AddParameter(std::string{"--vsock_guest_cid="} +
+    adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
                             std::to_string(instance.vsock_guest_cid()));
     process_monitor->StartSubprocess(std::move(adb_tunnel),
                                      GetOnSubprocessExitCallback(config));
diff --git a/host/frontend/gcastv2/https/HTTPServer.cpp b/host/frontend/gcastv2/https/HTTPServer.cpp
index e472142..1a40420 100644
--- a/host/frontend/gcastv2/https/HTTPServer.cpp
+++ b/host/frontend/gcastv2/https/HTTPServer.cpp
@@ -99,7 +99,7 @@
 
         std::string query;
 
-        auto separatorPos = path.find("?");
+        auto separatorPos = path.find('?');
         if (separatorPos != std::string::npos) {
             query = path.substr(separatorPos);
             path.erase(separatorPos);
diff --git a/host/frontend/gcastv2/libsource/InputSink.cpp b/host/frontend/gcastv2/libsource/InputSink.cpp
index e673358..ce9597d 100644
--- a/host/frontend/gcastv2/libsource/InputSink.cpp
+++ b/host/frontend/gcastv2/libsource/InputSink.cpp
@@ -123,6 +123,8 @@
       makeFdNonblocking(s);
 
       mClientFd = s;
+      mRunLoop->postSocketRecv(
+        mClientFd, makeSafeCallback(this, &InputSink::onSocketRecv));
     }
   }
 
@@ -151,6 +153,27 @@
   }
 }
 
+void InputSink::onSocketRecv() {
+  if (mClientFd < 0) return;
+
+  char buff[512];
+  auto n = recv(mClientFd, buff, sizeof(buff), 0 /* flags */);
+  if (n > 0) {
+    LOG(INFO) << "Discarding " << n << " bytes received from the input device.";
+    mRunLoop->postSocketRecv(
+        mClientFd, makeSafeCallback(this, &InputSink::onSocketRecv));
+  } else {
+    // Client disconnected
+    if (n < 0) {
+      auto errno_save = errno;
+      LOG(ERROR) << "Error receiving from socket: " << strerror(errno_save);
+    }
+    mRunLoop->cancelSocket(mClientFd);
+    close(mClientFd);
+    mClientFd = -1;
+  }
+}
+
 void InputSink::onSocketSend() {
   std::lock_guard autoLock(mLock);
 
diff --git a/host/frontend/gcastv2/libsource/include/source/InputSink.h b/host/frontend/gcastv2/libsource/include/source/InputSink.h
index ba5af91..38af13b 100644
--- a/host/frontend/gcastv2/libsource/include/source/InputSink.h
+++ b/host/frontend/gcastv2/libsource/include/source/InputSink.h
@@ -54,6 +54,7 @@
   bool mWriteVirtioInput;
 
   void onServerConnection();
+  void onSocketRecv();
   void onSocketSend();
 
   void sendRawEvents(const void* evt_buffer, size_t length);
diff --git a/host/frontend/gcastv2/webrtc/AdbWebSocketHandler.cpp b/host/frontend/gcastv2/webrtc/AdbWebSocketHandler.cpp
index ae0f8af..dcb6d50 100644
--- a/host/frontend/gcastv2/webrtc/AdbWebSocketHandler.cpp
+++ b/host/frontend/gcastv2/webrtc/AdbWebSocketHandler.cpp
@@ -161,7 +161,7 @@
 }
 
 int AdbWebSocketHandler::setupSocket(const std::string &adb_host_and_port) {
-    auto colonPos = adb_host_and_port.find(":");
+    auto colonPos = adb_host_and_port.find(':');
     if (colonPos == std::string::npos) {
         return -EINVAL;
     }
diff --git a/host/frontend/gcastv2/webrtc/DTLS.cpp b/host/frontend/gcastv2/webrtc/DTLS.cpp
index ea84842..6ae6c9c 100644
--- a/host/frontend/gcastv2/webrtc/DTLS.cpp
+++ b/host/frontend/gcastv2/webrtc/DTLS.cpp
@@ -166,7 +166,7 @@
         return 0;
     }
 
-    auto spacePos = me->mRemoteFingerprint.find(" ");
+    auto spacePos = me->mRemoteFingerprint.find(' ');
     CHECK(spacePos != std::string::npos);
     auto digestName = me->mRemoteFingerprint.substr(0, spacePos);
     CHECK(!strcasecmp(digestName.c_str(), "sha-256"));
diff --git a/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp b/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
index c05b9d6..eabe180 100644
--- a/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
+++ b/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
@@ -577,7 +577,7 @@
 }
 
 void MyWebSocketHandler::parseOptions(const std::string &pathAndQuery) {
-    auto separatorPos = pathAndQuery.find("?");
+    auto separatorPos = pathAndQuery.find('?');
 
     if (separatorPos == std::string::npos) {
         return;
@@ -587,7 +587,7 @@
     for (auto name : components) {
         bool boolValue = true;
 
-        separatorPos = name.find("=");
+        separatorPos = name.find('=');
         if (separatorPos != std::string::npos) {
             boolValue = false;
 
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 3676a73..f391f51 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -69,13 +69,6 @@
   // the HAL search path allows for fallbacks, and fallbacks in conjunction
   // with properities lead to non-deterministic behavior while loading the
   // HALs.
-  if (gpu_mode == vsoc::kGpuModeDrmVirgl) {
-    return {
-      "androidboot.hardware.gralloc=minigbm",
-      "androidboot.hardware.hwcomposer=drm_minigbm",
-      "androidboot.hardware.egl=mesa",
-    };
-  }
   if (gpu_mode == vsoc::kGpuModeGuestSwiftshader) {
     return {
         "androidboot.hardware.gralloc=cutf_ashmem",
@@ -84,10 +77,26 @@
         "androidboot.hardware.vulkan=pastel",
     };
   }
+
+  // Try to load the Nvidia modeset kernel module. Running Crosvm with Nvidia's EGL library on a
+  // fresh machine after a boot will fail because the Nvidia EGL library will fork to run the
+  // nvidia-modprobe command and the main Crosvm process will abort after receiving the exit signal
+  // of the forked child which is interpreted as a failure.
+  cvd::Command modprobe_cmd("/usr/bin/nvidia-modprobe");
+  modprobe_cmd.AddParameter("--modeset");
+  modprobe_cmd.Start().Wait();
+
+  if (gpu_mode == vsoc::kGpuModeDrmVirgl) {
+    return {
+      "androidboot.hardware.gralloc=minigbm",
+      "androidboot.hardware.hwcomposer=drm_minigbm",
+      "androidboot.hardware.egl=mesa",
+    };
+  }
   if (gpu_mode == vsoc::kGpuModeGfxStream) {
     return {
         "androidboot.hardware.gralloc=minigbm",
-        "androidboot.hardware.hwcomposer=ranchu",
+        "androidboot.hardware.hwcomposer=drm_minigbm",
         "androidboot.hardware.egl=emulation",
         "androidboot.hardware.vulkan=ranchu",
         "androidboot.hardware.gltransport=virtio-gpu-pipe",
diff --git a/shared/auto/manifest.xml b/shared/auto/manifest.xml
index 7fcdd4d..60e9a85 100644
--- a/shared/auto/manifest.xml
+++ b/shared/auto/manifest.xml
@@ -9,7 +9,7 @@
 */
 -->
 <!-- Android Auto Embedded specific HALs-->
-<manifest version="1.0" type="device" target-level="4">
+<manifest version="1.0" type="device" target-level="5">
     <hal format="hidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <transport>hwbinder</transport>
diff --git a/shared/config/init.vendor.rc b/shared/config/init.vendor.rc
index 1281ef1..c876617 100644
--- a/shared/config/init.vendor.rc
+++ b/shared/config/init.vendor.rc
@@ -80,6 +80,9 @@
 on post-fs-data
     start vport_trigger
 
+    mkdir /data/vendor/modem_dump 0777 system system
+    mkdir /data/vendor/radio 0777 system system
+
 
 on late-fs
     # Wait for keymaster
@@ -125,7 +128,7 @@
     disabled
     oneshot
 
-service socket_vsock_proxy /vendor/bin/socket_vsock_proxy -tcp_port=5555 -vsock_port=6520
+service socket_vsock_proxy /vendor/bin/socket_vsock_proxy -server=vsock -tcp_port=5555 -vsock_port=6520
 
 
 service vport_trigger /vendor/bin/vport_trigger
diff --git a/shared/config/manifest.xml b/shared/config/manifest.xml
index 2d728e9..a20ac4e 100644
--- a/shared/config/manifest.xml
+++ b/shared/config/manifest.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-<manifest version="1.0" type="device" target-level="4">
+<manifest version="1.0" type="device" target-level="5">
     <kernel  target-level="5" />
     <hal format="hidl">
         <name>android.hardware.audio</name>
@@ -95,15 +95,6 @@
             <instance>legacy/0</instance>
         </interface>
     </hal>
-    <hal format="hidl">
-        <name>android.hardware.configstore</name>
-        <transport>hwbinder</transport>
-        <version>1.1</version>
-        <interface>
-            <name>ISurfaceFlingerConfigs</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <!-- TODO (b/130078386):
     <hal format="hidl">
         <name>android.hardware.confirmationui</name>
@@ -185,15 +176,6 @@
     </hal>
     -->
     <hal format="hidl">
-        <name>android.hardware.identity</name>
-        <transport>hwbinder</transport>
-        <version>1.0</version>
-        <interface>
-            <name>IIdentityCredentialStore</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <transport>hwbinder</transport>
         <version>4.1</version>
@@ -203,15 +185,6 @@
         </interface>
     </hal>
     <hal format="hidl">
-        <name>android.hardware.light</name>
-        <transport>hwbinder</transport>
-        <version>2.0</version>
-        <interface>
-            <name>ILight</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <transport>hwbinder</transport>
         <version>1.0</version>
diff --git a/shared/device.mk b/shared/device.mk
index 8986f0d..9a0c03a 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -20,7 +20,7 @@
 # Enable userspace reboot
 $(call inherit-product, $(SRC_TARGET_DIR)/product/userspace_reboot.mk)
 
-PRODUCT_SHIPPING_API_LEVEL := 29
+PRODUCT_SHIPPING_API_LEVEL := 30
 PRODUCT_BUILD_BOOT_IMAGE := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
 DISABLE_RILD_OEM_HOOK := true
@@ -64,7 +64,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
     wlan.driver.status=ok
 
-#
+# aes-256-heh default is not supported in standard kernels.
+PRODUCT_PROPERTY_OVERRIDES += ro.crypto.volume.filenames_mode=aes-256-cts
+
 # Packages for various GCE-specific utilities
 #
 PRODUCT_PACKAGES += \
@@ -286,7 +288,7 @@
 
 # Identity Credential
 PRODUCT_PACKAGES += \
-    android.hardware.identity@1.0-service.example
+    android.hardware.identity-service.example
 
 # Input Classifier HAL
 PRODUCT_PACKAGES += \
@@ -311,9 +313,7 @@
 # Lights
 #
 PRODUCT_PACKAGES += \
-    lights.cutf \
-    android.hardware.light@2.0-impl \
-    android.hardware.light@2.0-service
+    android.hardware.lights-service.example \
 
 #
 # Keymaster HAL
diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts
index f44f0be..c20b56c 100644
--- a/shared/sepolicy/vendor/file_contexts
+++ b/shared/sepolicy/vendor/file_contexts
@@ -63,6 +63,7 @@
 /vendor/bin/hw/android\.hardware\.dumpstate@1\.1-service\.cuttlefish  u:object_r:hal_dumpstate_impl_exec:s0
 /vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service\.software  u:object_r:hal_gatekeeper_default_exec:s0
 /vendor/bin/hw/android\.hardware\.health\.storage@1\.0-service\.cuttlefish u:object_r:hal_health_storage_default_exec:s0
+/vendor/bin/hw/android\.hardware\.lights-service\.example u:object_r:hal_light_default_exec:s0
 /vendor/bin/hw/android\.hardware\.neuralnetworks@1\.3-service-sample-.*   u:object_r:hal_neuralnetworks_sample_exec:s0
 /vendor/bin/hw/android\.hardware\.vibrator@1\.x-service\.example u:object_r:hal_vibrator_default_exec:s0
 /vendor/bin/hw/android\.hardware\.tv\.cec@1\.0-service\.mock u:object_r:hal_tv_cec_mock_exec:s0
diff --git a/shared/sepolicy/vendor/google/file.te b/shared/sepolicy/vendor/google/file.te
new file mode 100644
index 0000000..6215415
--- /dev/null
+++ b/shared/sepolicy/vendor/google/file.te
@@ -0,0 +1 @@
+type radio_vendor_data_file, file_type, data_file_type, mlstrustedobject;
diff --git a/shared/sepolicy/vendor/google/file_contexts b/shared/sepolicy/vendor/google/file_contexts
new file mode 100644
index 0000000..fa35cd3
--- /dev/null
+++ b/shared/sepolicy/vendor/google/file_contexts
@@ -0,0 +1 @@
+/data/vendor/radio(/.*)?               u:object_r:radio_vendor_data_file:s0
diff --git a/shared/sepolicy/vendor/google/logger_app.te b/shared/sepolicy/vendor/google/logger_app.te
new file mode 100644
index 0000000..4eb329e
--- /dev/null
+++ b/shared/sepolicy/vendor/google/logger_app.te
@@ -0,0 +1,15 @@
+type logger_app, domain;
+
+# Taken from bonito-sepolicy:
+# https://cs.android.com/android/_/android/device/google/bonito-sepolicy/+/5396ef0aa04dc69ed04ecbc7f55eacf2a76b040b:vendor/qcom/common/logger_app.te;drc=dd2c2053296b0c00b5ef103adcabb8cd82eb0045
+userdebug_or_eng(`
+  app_domain(logger_app)
+  net_domain(logger_app)
+
+  allow logger_app app_api_service:service_manager find;
+  allow logger_app surfaceflinger_service:service_manager find;
+  allow logger_app radio_vendor_data_file:file create_file_perms;
+  allow logger_app radio_vendor_data_file:file rw_file_perms;
+  allow logger_app radio_vendor_data_file:dir create_dir_perms;
+  allow logger_app radio_vendor_data_file:dir rw_dir_perms;
+')
diff --git a/shared/sepolicy/vendor/google/seapp_contexts b/shared/sepolicy/vendor/google/seapp_contexts
index 0be8810..0ba2c3a 100644
--- a/shared/sepolicy/vendor/google/seapp_contexts
+++ b/shared/sepolicy/vendor/google/seapp_contexts
@@ -1,2 +1,3 @@
 # Ramdump app
 user=_app seinfo=platform name=com.android.ramdump domain=ramdump_app type=app_data_file levelFrom=all
+user=_app seinfo=platform name=com.android.pixellogger domain=logger_app type=app_data_file levelFrom=all
diff --git a/shared/sepolicy/vendor/hal_dumpstate_impl.te b/shared/sepolicy/vendor/hal_dumpstate_impl.te
index 33e2e9d..84c0339 100644
--- a/shared/sepolicy/vendor/hal_dumpstate_impl.te
+++ b/shared/sepolicy/vendor/hal_dumpstate_impl.te
@@ -1,6 +1,9 @@
 type hal_dumpstate_impl, domain;
 type hal_dumpstate_impl_exec, exec_type, vendor_file_type, file_type;
+type hal_dumpstate_prop, property_type;
 
 hal_server_domain(hal_dumpstate_impl, hal_dumpstate)
 
 init_daemon_domain(hal_dumpstate_impl)
+
+set_prop(hal_dumpstate_impl, hal_dumpstate_prop)
diff --git a/shared/sepolicy/vendor/property_contexts b/shared/sepolicy/vendor/property_contexts
index 12abbe1..5aacb9c 100644
--- a/shared/sepolicy/vendor/property_contexts
+++ b/shared/sepolicy/vendor/property_contexts
@@ -1,5 +1,6 @@
 bt.rootcanal_mac_address  u:object_r:hal_bluetooth_sim_prop:s0
 bt.rootcanal_test_console  u:object_r:hal_bluetooth_sim_prop:s0
+persist.vendor.logging_enabled  u:object_r:hal_dumpstate_prop:s0
 qemu.sf.back_camera_caps  u:object_r:hal_camera_prop:s0
 qemu.sf.front_camera_caps  u:object_r:hal_camera_prop:s0
 qemu.sf.fake_camera  u:object_r:hal_camera_prop:s0
diff --git a/shared/sepolicy/vendor/vsock_logcat.te b/shared/sepolicy/vendor/vsock_logcat.te
index 405a362..7b7e8ff 100644
--- a/shared/sepolicy/vendor/vsock_logcat.te
+++ b/shared/sepolicy/vendor/vsock_logcat.te
@@ -12,6 +12,6 @@
 
 allow vsock_logcat device:dir w_dir_perms;
 allow vsock_logcat device:fifo_file create_file_perms;
-allow vsock_logcat kmsg_device:chr_file write;
+allow vsock_logcat kmsg_device:chr_file rw_file_perms;
 allow vsock_logcat self:capability net_admin;
 allow vsock_logcat self:{ socket vsock_socket } create_socket_perms_no_ioctl;
diff --git a/shared/tv/manifest.xml b/shared/tv/manifest.xml
index ba78430..0dc4a45 100644
--- a/shared/tv/manifest.xml
+++ b/shared/tv/manifest.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-<manifest version="1.0" type="device" target-level="4">
+<manifest version="1.0" type="device" target-level="5">
      <!-- FIXME: Implement tv.cec HAL
      <hal format="hidl">
         <name>android.hardware.tv.cec</name>
diff --git a/tests/hal/Android.bp b/tests/hal/Android.bp
index f8a3d83..41cb2c0 100644
--- a/tests/hal/Android.bp
+++ b/tests/hal/Android.bp
@@ -2,6 +2,7 @@
     name: "hal_implementation_test",
     srcs: ["hal_implementation_test.cpp"],
     static_libs: [
+        "libaidlmetadata",
         "libhidlmetadata",
         "libhidl-gen-utils",
     ],
diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp
index f0301df..3d4fd47 100644
--- a/tests/hal/hal_implementation_test.cpp
+++ b/tests/hal/hal_implementation_test.cpp
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <aidl/metadata.h>
 #include <android-base/logging.h>
+#include <android-base/strings.h>
 #include <gtest/gtest.h>
 #include <hidl/metadata.h>
 #include <hidl-util/FQName.h>
@@ -21,7 +23,7 @@
 
 using namespace android;
 
-static const std::set<std::string> kKnownMissing = {
+static const std::set<std::string> kKnownMissingHidl = {
     "android.frameworks.bufferhub@1.0",
     "android.frameworks.cameraservice.device@2.0",
     "android.frameworks.vr.composer@1.0",
@@ -47,6 +49,7 @@
     "android.hardware.cas.native@1.0",
     "android.hardware.confirmationui@1.0",
     "android.hardware.contexthub@1.0",
+    "android.hardware.configstore@1.1", // deprecated, see b/149050985, b/149050733
     "android.hardware.fastboot@1.0",
     "android.hardware.gnss.measurement_corrections@1.0",
     "android.hardware.gnss.visibility_control@1.0",
@@ -61,6 +64,7 @@
     "android.hardware.health@1.0",
     "android.hardware.ir@1.0",
     "android.hardware.keymaster@3.0",
+    "android.hardware.light@2.0",
     "android.hardware.media.bufferpool@1.0",
     "android.hardware.media.bufferpool@2.0",
     "android.hardware.memtrack@1.0",
@@ -92,8 +96,21 @@
     "android.hidl.memory.token@1.0",
 };
 
+static const std::set<std::string> kKnownMissingAidl = {
+    // types-only packages, which never expect a default implementation
+    "android.hardware.common.NativeHandle",
+    "android.hardware.graphics.common.ExtendableType",
+
+    // These KeyMaster types are in an AIDL types-only HAL because they're used
+    // by the Identity Credential AIDL HAL. Remove this when fully porting
+    // KeyMaster to AIDL.
+    "android.hardware.keymaster.HardwareAuthToken",
+    "android.hardware.keymaster.HardwareAuthenticatorType",
+    "android.hardware.keymaster.Timestamp",
+};
+
 // AOSP packages which are never considered
-static bool isPackageWhitelist(const FQName& name) {
+static bool isHidlPackageWhitelist(const FQName& name) {
     static std::vector<std::string> gAospExclude = {
         // packages not implemented now that we never expect to be implemented
         "android.hardware.tests",
@@ -108,22 +125,22 @@
     return false;
 }
 
-static bool isAospInterface(const FQName& name) {
-    static std::vector<std::string> gAospPackages = {
+static bool isAospHidlInterface(const FQName& name) {
+    static const std::vector<std::string> kAospPackages = {
         "android.hidl",
         "android.hardware",
         "android.frameworks",
         "android.system",
     };
-    for (const std::string& package : gAospPackages) {
-        if (name.inPackage(package) && !isPackageWhitelist(name)) {
+    for (const std::string& package : kAospPackages) {
+        if (name.inPackage(package) && !isHidlPackageWhitelist(name)) {
             return true;
         }
     }
     return false;
 }
 
-static std::set<FQName> allTreeInterfaces() {
+static std::set<FQName> allTreeHidlInterfaces() {
     std::set<FQName> ret;
     for (const auto& iface : HidlInterfaceMetadata::all()) {
         FQName f;
@@ -133,11 +150,10 @@
     return ret;
 }
 
-static std::set<FQName> allManifestInstances() {
+static std::set<FQName> allHidlManifestInterfaces() {
     std::set<FQName> ret;
     auto setInserter = [&] (const vintf::ManifestInstance& i) -> bool {
         if (i.format() != vintf::HalFormat::HIDL) {
-            std::cout << "[ WARNING  ] Not checking non-HIDL instance: " << i.description() << std::endl;
             return true;  // continue
         }
         ret.insert(i.getFqInstance().getFqName());
@@ -148,18 +164,38 @@
     return ret;
 }
 
-TEST(Hidl, IsAospDevice) {
-    for (const FQName& name : allManifestInstances()) {
-        EXPECT_TRUE(isAospInterface(name)) << name.string();
+static bool isAospAidlInterface(const std::string& name) {
+    return base::StartsWith(name, "android.") &&
+        !base::StartsWith(name, "android.automotive.") &&
+        !base::StartsWith(name, "android.hardware.automotive.");
+}
+
+static std::set<std::string> allAidlManifestInterfaces() {
+    std::set<std::string> ret;
+    auto setInserter = [&] (const vintf::ManifestInstance& i) -> bool {
+        if (i.format() != vintf::HalFormat::AIDL) {
+            return true;  // continue
+        }
+        ret.insert(i.package() + "." + i.interface());
+        return true;  // continue
+    };
+    vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
+    vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
+    return ret;
+}
+
+TEST(Hal, AllHidlInterfacesAreInAosp) {
+    for (const FQName& name : allHidlManifestInterfaces()) {
+        EXPECT_TRUE(isAospHidlInterface(name)) << name.string();
     }
 }
 
-TEST(Hidl, InterfacesImplemented) {
+TEST(Hal, HidlInterfacesImplemented) {
     // instances -> major version -> minor versions
     std::map<std::string, std::map<size_t, std::set<size_t>>> unimplemented;
 
-    for (const FQName& f : allTreeInterfaces()) {
-        if (!isAospInterface(f)) continue;
+    for (const FQName& f : allTreeHidlInterfaces()) {
+        if (!isAospHidlInterface(f)) continue;
 
         unimplemented[f.package()][f.getPackageMajorVersion()].insert(f.getPackageMinorVersion());
     }
@@ -167,11 +203,12 @@
     // we'll be removing items from this which we know are missing
     // in order to be left with those elements which we thought we
     // knew were missing but are actually present
-    std::set<std::string> thoughtMissing = kKnownMissing;
+    std::set<std::string> thoughtMissing = kKnownMissingHidl;
 
-    for (const FQName& f : allManifestInstances()) {
+    for (const FQName& f : allHidlManifestInterfaces()) {
         if (thoughtMissing.erase(f.getPackageAndVersion().string()) > 0) {
-             std::cout << "[ WARNING  ] Instance in missing list, but available: " << f.string() << std::endl;
+             std::cout << "[ WARNING  ] Instance in missing list, but available: "
+                       << f.string() << std::endl;
         }
 
         std::set<size_t>& minors = unimplemented[f.package()][f.getPackageMajorVersion()];
@@ -200,6 +237,53 @@
     }
 
     for (const std::string& missing : thoughtMissing) {
-        std::cout << "[ WARNING  ] Instance in missing list, and cannot find it anywhere: " << missing << std::endl;
+        std::cout << "[ WARNING  ] Instance in missing list and cannot find it anywhere: "
+                  << missing << std::endl;
+    }
+}
+
+TEST(Hal, AllAidlInterfacesAreInAosp) {
+    for (const std::string& name : allAidlManifestInterfaces()) {
+        EXPECT_TRUE(isAospAidlInterface(name)) << name;
+    }
+}
+
+TEST(Hal, AidlInterfacesImplemented) {
+    std::set<std::string> manifest = allAidlManifestInterfaces();
+    std::set<std::string> thoughtMissing = kKnownMissingAidl;
+
+    for (const auto& iface : AidlInterfaceMetadata::all()) {
+        ASSERT_FALSE(iface.types.empty()) << iface.name;  // sanity
+        if (!isAospAidlInterface(iface.name)) continue;
+        if (iface.stability != "vintf") continue;
+
+        bool hasRegistration = false;
+        bool knownMissing = false;
+        for (const std::string& type : iface.types) {
+            if (manifest.erase(type) > 0) hasRegistration = true;
+            if (thoughtMissing.erase(type) > 0) knownMissing = true;
+        }
+
+        if (knownMissing) {
+            if (hasRegistration) {
+                std::cout << "[ WARNING  ] Interface in missing list, but available: " << iface.name
+                          << " which declares the following types:\n    "
+                          << base::Join(iface.types, "\n    ") << std::endl;
+            }
+
+            continue;
+        }
+
+        EXPECT_TRUE(hasRegistration) << iface.name << " which declares the following types:\n    "
+            << base::Join(iface.types, "\n    ") << std::endl;
+    }
+
+    for (const std::string& iface : thoughtMissing) {
+        std::cout << "[ WARNING  ] Interface in manifest list and cannot find it anywhere: "
+                  << iface << std::endl;
+    }
+
+    for (const std::string& iface : manifest) {
+        std::cout << "[ WARNING  ] Can't find manifest entry in tree: " << iface << std::endl;
     }
 }
diff --git a/vsoc_x86_noapex/BoardConfig.mk b/vsoc_x86_noapex/BoardConfig.mk
index 109e567..934b3e9 100644
--- a/vsoc_x86_noapex/BoardConfig.mk
+++ b/vsoc_x86_noapex/BoardConfig.mk
@@ -21,4 +21,3 @@
 include device/google/cuttlefish/vsoc_x86/BoardConfig.mk
 
 TARGET_FLATTEN_APEX := true
-BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(wildcard device/google/cuttlefish_kernel/5.4-x86_64/*.ko)