Merge "Delete cuttlefish_thread.h"
diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp
index b85cf7c..f3fff8a 100644
--- a/common/libs/fs/shared_fd.cpp
+++ b/common/libs/fs/shared_fd.cpp
@@ -86,26 +86,6 @@
 
 namespace cvd {
 
-bool FileInstance::CopyFrom(FileInstance& in) {
-  std::vector<char> buffer(8192);
-  while (true) {
-    ssize_t num_read = in.Read(buffer.data(), buffer.size());
-    if (!num_read) {
-      return true;
-    }
-    if (num_read == -1) {
-      return false;
-    }
-    if (num_read > 0) {
-      if (Write(buffer.data(), num_read) != num_read) {
-        // The caller will have to log an appropriate message.
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
 bool FileInstance::CopyFrom(FileInstance& in, size_t length) {
   std::vector<char> buffer(8192);
   while (length > 0) {
@@ -143,16 +123,6 @@
   fd_ = -1;
 }
 
-void FileInstance::Identify(const char* identity) {
-  std::stringstream identity_stream;
-  identity_stream << "fd=" << fd_ << " @" << this << " is " << identity;
-  identity_ = identity_stream.str();
-  std::stringstream message;
-  message << __FUNCTION__ << ": " << identity_;
-  std::string message_str = message.str();
-  Log(message_str.c_str());
-}
-
 bool FileInstance::IsSet(fd_set* in) const {
   if (IsOpen() && FD_ISSET(fd_, in)) {
     return true;
@@ -232,23 +202,6 @@
   *len = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
 }
 
-SharedFD SharedFD::SocketSeqPacketServer(const char* name, mode_t mode) {
-  return SocketLocalServer(name, false, SOCK_SEQPACKET, mode);
-}
-
-SharedFD SharedFD::SocketSeqPacketClient(const char* name) {
-  return SocketLocalClient(name, false, SOCK_SEQPACKET);
-}
-
-SharedFD SharedFD::TimerFD(int clock, int flags) {
-  int fd = timerfd_create(clock, flags);
-  if (fd == -1) {
-    return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, errno)));
-  } else {
-    return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, 0)));
-  }
-}
-
 SharedFD SharedFD::Accept(const FileInstance& listener, struct sockaddr* addr,
                           socklen_t* addrlen) {
   return SharedFD(
@@ -281,11 +234,6 @@
   return std::shared_ptr<FileInstance>(new FileInstance(fd, errno));
 }
 
-SharedFD SharedFD::Epoll(int flags) {
-  int fd = epoll_create1(flags);
-  return std::shared_ptr<FileInstance>(new FileInstance(fd, errno));
-}
-
 SharedFD SharedFD::MemfdCreate(const char* name, unsigned int flags) {
   int fd = memfd_create_wrapper(name, flags);
   int error_num = errno;
diff --git a/common/libs/fs/shared_fd.h b/common/libs/fs/shared_fd.h
index 044c7cc..ef37d1f 100644
--- a/common/libs/fs/shared_fd.h
+++ b/common/libs/fs/shared_fd.h
@@ -66,26 +66,6 @@
 class FileInstance;
 
 /**
- * Describes the fields in msghdr that are honored by the *MsgAndFDs
- * calls.
- */
-struct InbandMessageHeader {
-  void* msg_name;
-  socklen_t msg_namelen;
-  struct iovec* msg_iov;
-  size_t msg_iovlen;
-  int msg_flags;
-
-  void Convert(struct msghdr* dest) const {
-    dest->msg_name = msg_name;
-    dest->msg_namelen = msg_namelen;
-    dest->msg_iov = msg_iov;
-    dest->msg_iovlen = msg_iovlen;
-    dest->msg_flags = msg_flags;
-  }
-};
-
-/**
  * Counted reference to a FileInstance.
  *
  * This is also the place where most new FileInstances are created. The creation
@@ -137,14 +117,12 @@
                          socklen_t* addrlen);
   static SharedFD Accept(const FileInstance& listener);
   static SharedFD Dup(int unmanaged_fd);
-  static SharedFD GetControlSocket(const char* name);
   // All SharedFDs have the O_CLOEXEC flag after creation. To remove use the
   // Fcntl or Dup functions.
   static SharedFD Open(const char* pathname, int flags, mode_t mode = 0);
   static SharedFD Creat(const char* pathname, mode_t mode);
   static bool Pipe(SharedFD* fd0, SharedFD* fd1);
   static SharedFD Event(int initval = 0, int flags = 0);
-  static SharedFD Epoll(int flags = 0);
   static SharedFD MemfdCreate(const char* name, unsigned int flags = 0);
   static bool SocketPair(int domain, int type, int protocol, SharedFD* fd0,
                          SharedFD* fd1);
@@ -155,12 +133,9 @@
   static SharedFD SocketLocalServer(const char* name, bool is_abstract,
                                     int in_type, mode_t mode);
   static SharedFD SocketLocalServer(int port, int type);
-  static SharedFD SocketSeqPacketServer(const char* name, mode_t mode);
-  static SharedFD SocketSeqPacketClient(const char* name);
   static SharedFD VsockServer(unsigned int port, int type);
   static SharedFD VsockServer(int type);
   static SharedFD VsockClient(unsigned int cid, unsigned int port, int type);
-  static SharedFD TimerFD(int clock, int flags);
 
   bool operator==(const SharedFD& rhs) const { return value_ == rhs.value_; }
 
@@ -231,7 +206,6 @@
   // Otherwise an error will be set either on this file or the input.
   // The non-const reference is needed to avoid binding this to a particular
   // reference type.
-  bool CopyFrom(FileInstance& in);
   bool CopyFrom(FileInstance& in, size_t length);
 
   int UNMANAGED_Dup() {
@@ -248,27 +222,6 @@
     return rval;
   }
 
-  int EpollCtl(int op, cvd::SharedFD new_fd, struct epoll_event* event) {
-    errno = 0;
-    int rval = TEMP_FAILURE_RETRY(epoll_ctl(fd_, op, new_fd->fd_, event));
-    errno_ = errno;
-    return rval;
-  }
-
-  int EpollWait(struct epoll_event* events, int maxevents, int timeout) {
-    errno = 0;
-    int rval = TEMP_FAILURE_RETRY(epoll_wait(fd_, events, maxevents, timeout));
-    errno_ = errno;
-    return rval;
-  }
-
-  int Fchown(uid_t owner, gid_t group) {
-    errno = 0;
-    int rval = TEMP_FAILURE_RETRY(fchown(fd_, owner, group));
-    errno_ = errno;
-    return rval;
-  }
-
   int Fcntl(int command, int value) {
     errno = 0;
     int rval = TEMP_FAILURE_RETRY(fcntl(fd_, command, value));
@@ -276,24 +229,8 @@
     return rval;
   }
 
-  int Fstat(struct stat* buf) {
-    errno = 0;
-    int rval = TEMP_FAILURE_RETRY(fstat(fd_, buf));
-    errno_ = errno;
-    return rval;
-  }
-
   int GetErrno() const { return errno_; }
 
-  int GetSockOpt(int level, int optname, void* optval, socklen_t* optlen) {
-    errno = 0;
-    int rval = getsockopt(fd_, level, optname, optval, optlen);
-    if (rval == -1) {
-      errno_ = errno;
-    }
-    return rval;
-  }
-
   int GetSockName(struct sockaddr* addr, socklen_t* addrlen) {
     errno = 0;
     int rval = TEMP_FAILURE_RETRY(getsockname(fd_, addr, addrlen));
@@ -310,8 +247,6 @@
     return vm_socket.svm_port;
   }
 
-  void Identify(const char* identity);
-
   int Ioctl(int request, void* val = nullptr) {
     errno = 0;
     int rval = TEMP_FAILURE_RETRY(ioctl(fd_, request, val));
@@ -340,20 +275,6 @@
     return rval;
   }
 
-  void* Mmap(void* addr, size_t length, int prot, int flags, off_t offset) {
-    errno = 0;
-    void* rval = mmap(addr, length, prot, flags, fd_, offset);
-    errno_ = errno;
-    return rval;
-  }
-
-  ssize_t Pread(void* buf, size_t count, off_t offset) {
-    errno = 0;
-    ssize_t rval = TEMP_FAILURE_RETRY(pread(fd_, buf, count, offset));
-    errno_ = errno;
-    return rval;
-  }
-
   ssize_t Recv(void* buf, size_t len, int flags) {
     errno = 0;
     ssize_t rval = TEMP_FAILURE_RETRY(recv(fd_, buf, len, flags));
@@ -361,15 +282,6 @@
     return rval;
   }
 
-  ssize_t RecvFrom(void* buf, size_t len, int flags, struct sockaddr* src_addr,
-                   socklen_t* addr_len) {
-    errno = 0;
-    ssize_t rval =
-        TEMP_FAILURE_RETRY(recvfrom(fd_, buf, len, flags, src_addr, addr_len));
-    errno_ = errno;
-    return rval;
-  }
-
   ssize_t RecvMsg(struct msghdr* msg, int flags) {
     errno = 0;
     ssize_t rval = TEMP_FAILURE_RETRY(recvmsg(fd_, msg, flags));
@@ -377,36 +289,6 @@
     return rval;
   }
 
-  template <size_t SZ>
-  ssize_t RecvMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags,
-                        SharedFD (*new_fds)[SZ]) {
-    // We need to make some modifications to land the fds. Make it clear
-    // that there are no updates to the msg being passed in during this call.
-    struct msghdr msg;
-    msg_in.Convert(&msg);
-    union {
-      char buffer[CMSG_SPACE(SZ * sizeof(int))];
-      struct cmsghdr this_aligns_buffer;
-    } u;
-    msg.msg_control = u.buffer;
-    msg.msg_controllen = sizeof(u.buffer);
-
-    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
-    cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int));
-    cmsg->cmsg_level = SOL_SOCKET;
-    cmsg->cmsg_type = SCM_RIGHTS;
-    int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg));
-    for (size_t i = 0; i < SZ; ++i) {
-      fd_array[i] = -1;
-    }
-    ssize_t rval = RecvMsg(&msg, flags);
-    for (size_t i = 0; i < SZ; ++i) {
-      (*new_fds)[i] =
-          std::shared_ptr<FileInstance>(new FileInstance(fd_array[i], errno));
-    }
-    return rval;
-  }
-
   ssize_t Read(void* buf, size_t count) {
     errno = 0;
     ssize_t rval = TEMP_FAILURE_RETRY(read(fd_, buf, count));
@@ -428,29 +310,6 @@
     return rval;
   }
 
-  template <size_t SZ>
-  ssize_t SendMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags,
-                        const SharedFD (&fds)[SZ]) {
-    struct msghdr msg;
-    msg_in.Convert(&msg);
-    union {
-      char buffer[CMSG_SPACE(SZ * sizeof(int))];
-      struct cmsghdr this_aligns_buffer;
-    } u;
-    msg.msg_control = u.buffer;
-    msg.msg_controllen = sizeof(u.buffer);
-
-    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
-    cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int));
-    cmsg->cmsg_level = SOL_SOCKET;
-    cmsg->cmsg_type = SCM_RIGHTS;
-    int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg));
-    for (size_t i = 0; i < SZ; ++i) {
-      fd_array[i] = fds[i]->fd_;
-    }
-    return SendMsg(&msg, flags);
-  }
-
   int Shutdown(int how) {
     errno = 0;
     int rval = shutdown(fd_, how);
@@ -458,15 +317,6 @@
     return rval;
   }
 
-  ssize_t SendTo(const void* buf, size_t len, int flags,
-                 const struct sockaddr* dest_addr, socklen_t addrlen) {
-    errno = 0;
-    ssize_t rval =
-        TEMP_FAILURE_RETRY(sendto(fd_, buf, len, flags, dest_addr, addrlen));
-    errno_ = errno;
-    return rval;
-  }
-
   void Set(fd_set* dest, int* max_index) const;
 
   int SetSockOpt(int level, int optname, const void* optval, socklen_t optlen) {
@@ -492,21 +342,6 @@
     return strerror_buf_;
   }
 
-  int TimerGet(struct itimerspec* curr_value) {
-    errno = 0;
-    int rval = timerfd_gettime(fd_, curr_value);
-    errno_ = errno;
-    return rval;
-  }
-
-  int TimerSet(int flags, const struct itimerspec* new_value,
-               struct itimerspec* old_value) {
-    errno = 0;
-    int rval = timerfd_settime(fd_, flags, new_value, old_value);
-    errno_ = errno;
-    return rval;
-  }
-
   ssize_t Truncate(off_t length) {
     errno = 0;
     ssize_t rval = TEMP_FAILURE_RETRY(ftruncate(fd_, length));
@@ -521,13 +356,6 @@
     return rval;
   }
 
-  ssize_t WriteV(struct iovec* iov, int iovcount) {
-    errno = 0;
-    ssize_t rval = TEMP_FAILURE_RETRY(writev(fd_, iov, iovcount));
-    errno_ = errno;
-    return rval;
-  }
-
  private:
   FileInstance(int fd, int in_errno) : fd_(fd), errno_(in_errno) {
     // Ensure every file descriptor managed by a FileInstance has the CLOEXEC
diff --git a/common/libs/fs/shared_fd_test.cpp b/common/libs/fs/shared_fd_test.cpp
index 3423619..7ca6204 100644
--- a/common/libs/fs/shared_fd_test.cpp
+++ b/common/libs/fs/shared_fd_test.cpp
@@ -23,48 +23,17 @@
 
 #include <string>
 
-using cvd::InbandMessageHeader;
 using cvd::SharedFD;
 
-char hello[] = "Hello, world!";
 char pipe_message[] = "Testing the pipe";
 
 TEST(SendFD, Basic) {
-  char dirname[] = "/tmp/sfdtestXXXXXX";
-  char* socket = mkdtemp(dirname);
-  EXPECT_TRUE(socket != NULL);
-  std::string path(dirname);
-  path += "/s";
-  SharedFD server = SharedFD::SocketSeqPacketServer(path.c_str(), 0700);
-  EXPECT_TRUE(server->IsOpen());
-  int rval = fork();
-  EXPECT_NE(-1, rval);
-  if (!rval) {
-    struct iovec iov { hello, sizeof(hello) };
-    SharedFD client = SharedFD::SocketSeqPacketClient(path.c_str());
-    InbandMessageHeader hdr{};
-    hdr.msg_iov = &iov;
-    hdr.msg_iovlen = 1;
-    SharedFD fds[2];
-    SharedFD::Pipe(fds, fds + 1);
-    ssize_t rval = client->SendMsgAndFDs(hdr, 0, fds);
-    printf("SendMsg sent %zd (%s)\n", rval, client->StrError());
-    exit(0);
-  }
-  server->Listen(2);
-  SharedFD peer = SharedFD::Accept(*server);
-  EXPECT_TRUE(peer->IsOpen());
-  char buf[80];
-  struct iovec iov { buf, sizeof(buf) };
-  InbandMessageHeader hdr{};
-  hdr.msg_iov = &iov;
-  hdr.msg_iovlen = 1;
   SharedFD fds[2];
-  peer->RecvMsgAndFDs(hdr, 0, &fds);
-  EXPECT_EQ(0, strcmp(buf, hello));
+  SharedFD::Pipe(fds, fds + 1);
   EXPECT_TRUE(fds[0]->IsOpen());
   EXPECT_TRUE(fds[1]->IsOpen());
   EXPECT_EQ(sizeof(pipe_message), fds[1]->Write(pipe_message, sizeof(pipe_message)));
+  char buf[80];
   EXPECT_EQ(sizeof(pipe_message), fds[0]->Read(buf, sizeof(buf)));
   EXPECT_EQ(0, strcmp(buf, pipe_message));
 }
diff --git a/common/libs/utils/size_utils.cpp b/common/libs/utils/size_utils.cpp
index c43bf96..0f7ed3c 100644
--- a/common/libs/utils/size_utils.cpp
+++ b/common/libs/utils/size_utils.cpp
@@ -20,19 +20,6 @@
 
 namespace cvd {
 
-uint32_t AlignToPageSize(uint32_t val) {
-  static uint32_t page_size = sysconf(_SC_PAGESIZE);
-  return ((val + (page_size - 1)) / page_size) * page_size;
-}
-
-uint32_t RoundUpToNextPowerOf2(uint32_t val) {
-  uint32_t power_of_2 = 1;
-  while (power_of_2 < val) {
-    power_of_2 *= 2;
-  }
-  return power_of_2;
-}
-
 uint32_t AlignToPowerOf2(uint32_t val, uint8_t align_log) {
   uint32_t align = 1 << align_log;
   return ((val + (align - 1)) / align) * align;
diff --git a/common/libs/utils/size_utils.h b/common/libs/utils/size_utils.h
index 1d34493..42044ec 100644
--- a/common/libs/utils/size_utils.h
+++ b/common/libs/utils/size_utils.h
@@ -19,12 +19,6 @@
 
 namespace cvd {
 
-// Returns the smallest multiple of PAGE_SIZE greater than or equal to val.
-uint32_t AlignToPageSize(uint32_t val);
-
-// Returns the smallest power of two greater than or equal to val.
-uint32_t RoundUpToNextPowerOf2(uint32_t val);
-
 // Returns the smallest multiple of 2^align_log greater than or equal to val.
 uint32_t AlignToPowerOf2(uint32_t val, uint8_t align_log);
 
diff --git a/guest/hals/ril/cuttlefish_ril.cpp b/guest/hals/ril/cuttlefish_ril.cpp
index 40fc393..27559da 100644
--- a/guest/hals/ril/cuttlefish_ril.cpp
+++ b/guest/hals/ril/cuttlefish_ril.cpp
@@ -1214,33 +1214,6 @@
                                  sizeof(gCdmaSubscriptionType));
 }
 
-static void request_enable_uicc_applications(int /*request*/, void* data,
-                                             size_t datalen,
-                                             RIL_Token t) {
-  ALOGV("Enable uicc applications.");
-
-  if (data == NULL || datalen != sizeof(int)) {
-    gce_ril_env->OnRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0);
-    return;
-  }
-
-  bool enable = *(int *)(data) != 0;
-
-  ALOGV("areUiccApplicationsEnabled change from %d to %d", areUiccApplicationsEnabled, enable);
-
-  areUiccApplicationsEnabled = enable;
-
-  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-}
-
-static void request_are_uicc_applications_enabled(int /*request*/, void* /*data*/,
-                                                  size_t /*datalen*/,
-                                                  RIL_Token t) {
-  ALOGV("Getting whether uicc applications are enabled.");
-
-  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &areUiccApplicationsEnabled, sizeof(bool));
-}
-
 static void request_cdma_set_subscription_source(int /*request*/, void* data,
                                                  size_t /*datalen*/,
                                                  RIL_Token t) {
@@ -1385,20 +1358,6 @@
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
 }
 
-static void request_set_carrier_restrictions4(void* /*data*/,
-                                              size_t /*datalen*/,
-                                              RIL_Token t) {
-  ALOGV("Set carrier restrictions is not supported");
-  // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices
-  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
-}
-
-static void request_get_carrier_restrictions4(RIL_Token t) {
-  ALOGV("Get carrier restrictions is not supported");
-  // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices
-  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
-}
-
 static RIL_RadioState gce_ril_current_state() {
   ALOGV("Reporting radio state %d", gRadioPowerState);
   return gRadioPowerState;
@@ -2207,12 +2166,6 @@
   return;
 }
 
-static void request_start_network_scan4(RIL_Token t) {
-  ALOGV("Scanning network 1.4");
-  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-  return;
-}
-
 static void request_set_preferred_network_type_bitmap(int /*request*/, void* data,
                                                size_t /*datalen*/,
                                                RIL_Token t) {
@@ -2270,27 +2223,54 @@
 }
 
 // New functions after Q.
-static void request_set_signal_strength_reporting_criteria_1_5(int /*request*/, void* /*data*/,
-                                                               size_t /*datalen*/, RIL_Token t) {
-  ALOGV("request_set_signal_strength_reporting_criteria_1_5 - void");
+static void request_set_signal_strength_reporting_criteria(int /*request*/, void* /*data*/,
+                                                           size_t /*datalen*/, RIL_Token t) {
+    ALOGV("request_set_signal_strength_reporting_criteria - void");
+    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+    return;
+}
+
+static void request_enable_uicc_applications(int /*request*/, void* data,
+                                             size_t datalen,
+                                             RIL_Token t) {
+  ALOGV("Enable uicc applications.");
+
+  if (data == NULL || datalen != sizeof(int)) {
+    gce_ril_env->OnRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0);
+    return;
+  }
+
+  bool enable = *(int *)(data) != 0;
+
+  ALOGV("areUiccApplicationsEnabled change from %d to %d", areUiccApplicationsEnabled, enable);
+
+  areUiccApplicationsEnabled = enable;
+
+  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+}
+
+static void request_are_uicc_applications_enabled(int /*request*/, void* /*data*/,
+                                                  size_t /*datalen*/,
+                                                  RIL_Token t) {
+  ALOGV("Getting whether uicc applications are enabled.");
+
+  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &areUiccApplicationsEnabled, sizeof(bool));
+}
+
+static void request_set_radio_power(RIL_Token t) {
+  ALOGV("request_set_radio_power - void");
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
   return;
 }
 
-static void request_set_system_selection_channels_1_5(int /*request*/, RIL_Token t) {
-  ALOGV("request_set_system_selection_channels_1_5 - void");
+static void request_enter_sim_depersonalization(RIL_Token t) {
+  ALOGV("request_enter_sim_depersonalization - void");
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
   return;
 }
 
-static void request_start_network_scan_1_5(RIL_Token t) {
-  ALOGV("request_start_network_scan_1_5");
-  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-  return;
-}
-
-static void request_set_radio_power_1_5(RIL_Token t) {
-  ALOGV("request_set_radio_power_1_5");
+static void request_cdma_send_sms_expect_more(RIL_Token t) {
+  ALOGV("request_cdma_send_sms_expect_more - void");
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
   return;
 }
@@ -2523,9 +2503,6 @@
     case RIL_REQUEST_START_NETWORK_SCAN:
       request_start_network_scan(t);
       break;
-    case RIL_REQUEST_START_NETWORK_SCAN4:
-      request_start_network_scan4(t);
-      break;
     case RIL_REQUEST_GET_MODEM_STACK_STATUS:
       request_get_modem_stack_status(request, t);
       break;
@@ -2547,12 +2524,6 @@
     case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
       request_set_system_selection_channels(request, t);
       break;
-    case RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4:
-      request_set_carrier_restrictions4(data, datalen, t);
-      break;
-    case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4:
-      request_get_carrier_restrictions4(t);
-      break;
     case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
       gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
       break;
@@ -2579,8 +2550,8 @@
       break;
 
 // New requests after Q.
-    case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5:
-      request_set_signal_strength_reporting_criteria_1_5(request, data, datalen, t);
+    case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
+      request_set_signal_strength_reporting_criteria(request, data, datalen, t);
       break;
     case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
       request_enable_uicc_applications(request, data, datalen, t);
@@ -2588,14 +2559,14 @@
     case RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED:
       request_are_uicc_applications_enabled(request, data, datalen, t);
       break;
-    case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5:
-      request_set_system_selection_channels_1_5(request, t);
+    case RIL_REQUEST_SET_RADIO_POWER:
+      request_set_radio_power(t);
       break;
-    case RIL_REQUEST_START_NETWORK_SCAN_1_5:
-      request_start_network_scan_1_5(t);
+    case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION:
+      request_enter_sim_depersonalization(t);
       break;
-    case RIL_REQUEST_SET_RADIO_POWER_1_5:
-      request_set_radio_power_1_5(t);
+    case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
+      request_cdma_send_sms_expect_more(t);
       break;
     default:
       ALOGE("Request %d not supported.", request);
diff --git a/guest/hals/ril/libril/ril.cpp b/guest/hals/ril/libril/ril.cpp
index 4bb6b74..0660089 100644
--- a/guest/hals/ril/libril/ril.cpp
+++ b/guest/hals/ril/libril/ril.cpp
@@ -1073,10 +1073,7 @@
         case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
         case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
         case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS: return "RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS";
-        case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5: return "RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS5";
         case RIL_REQUEST_START_NETWORK_SCAN: return "RIL_REQUEST_START_NETWORK_SCAN";
-        case RIL_REQUEST_START_NETWORK_SCAN4: return "RIL_REQUEST_START_NETWORK_SCAN4";
-        case RIL_REQUEST_START_NETWORK_SCAN_1_5: return "RIL_REQUEST_START_NETWORK_SCAN5";
         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
         case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
         case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: return "QUERY_AVAILABLE_NETWORKS";
@@ -1168,12 +1165,10 @@
         case RIL_REQUEST_PULL_LCEDATA: return "PULL_LCEDATA";
         case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO";
         case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS";
-        case RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4: return "SET_CARRIER_RESTRICTIONS_1_4";
         case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS";
-        case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4: return "GET_CARRIER_RESTRICTIONS_1_4";
         case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION: return "SET_CARRIER_INFO_IMSI_ENCRYPTION";
-        case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5: return "SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5";
-        case RIL_REQUEST_SET_RADIO_POWER_1_5: return "SET_RADIO_POWER_1_5";
+        case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA: return "SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
+        case RIL_REQUEST_SET_RADIO_POWER: return "SET_RADIO_POWER";
         case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION: return "ENTER_SIM_DEPERSONALIZATION";
         case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE: return "CDMA_SEND_SMS_EXPECT_MORE";
         case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT";
diff --git a/guest/hals/ril/libril/ril.h b/guest/hals/ril/libril/ril.h
index 0067ba5..72700d5 100644
--- a/guest/hals/ril/libril/ril.h
+++ b/guest/hals/ril/libril/ril.h
@@ -80,13 +80,6 @@
  *                    RIL_REQUEST_SET_SIM_CARD_POWER,
  *                    RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION,
  *                    RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION
- *                    The new parameters for RIL_REQUEST_SETUP_DATA_CALL,
- *                    Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15
- *                    New data structure RIL_DataRegistrationStateResponse,
- *                    RIL_VoiceRegistrationStateResponse same is
- *                    used in RIL_REQUEST_DATA_REGISTRATION_STATE and
- *                    RIL_REQUEST_VOICE_REGISTRATION_STATE respectively.
- *                    New data structure RIL_OpenChannelParams.
  *                    RIL_REQUEST_START_NETWORK_SCAN
  *                    RIL_REQUEST_STOP_NETWORK_SCAN
  *                    RIL_UNSOL_NETWORK_SCAN_RESULT
@@ -94,8 +87,18 @@
  *                    RIL_REQUEST_ENABLE_MODEM
  *                    RIL_REQUEST_EMERGENCY_DIAL
  *                    RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS
+ *                    RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA
  *                    RIL_REQUEST_ENABLE_UICC_APPLICATIONS
  *                    RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED
+ *                    RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION
+ *                    RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE
+ *                    The new parameters for RIL_REQUEST_SETUP_DATA_CALL,
+ *                    Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15,
+ *                    RIL_Data_Call_Response_v12.
+ *                    New data structure RIL_DataRegistrationStateResponse, RIL_OpenChannelParams,
+ *                    RIL_VoiceRegistrationStateResponse same is
+ *                    used in RIL_REQUEST_DATA_REGISTRATION_STATE and
+ *                    RIL_REQUEST_VOICE_REGISTRATION_STATE respectively.
  */
 #define RIL_VERSION 12
 #define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name
@@ -2139,10 +2142,12 @@
 } RIL_ScanType;
 
 typedef enum {
-    GERAN = 0x01,   // GSM EDGE Radio Access Network
-    UTRAN = 0x02,   // Universal Terrestrial Radio Access Network
-    EUTRAN = 0x03,  // Evolved Universal Terrestrial Radio Access Network
-    NGRAN = 0x04,   // Next-Generation Radio Access Network
+    UNKNOWN = 0x00,     // Unknown Radio Access Network
+    GERAN = 0x01,       // GSM EDGE Radio Access Network
+    UTRAN = 0x02,       // Universal Terrestrial Radio Access Network
+    EUTRAN = 0x03,      // Evolved Universal Terrestrial Radio Access Network
+    NGRAN = 0x04,       // Next-Generation Radio Access Network
+    CDMA2000 = 0x05,    // CDMA 2000 Radio AccessNetwork
 } RIL_RadioAccessNetworks;
 
 typedef enum {
@@ -6449,28 +6454,6 @@
 #define RIL_REQUEST_STOP_KEEPALIVE 145
 
 /**
- * RIL_REQUEST_START_NETWORK_SCAN4
- *
- * Starts a new network scan
- *
- * Request to start a network scan with specified radio access networks with frequency bands and/or
- * channels.
- *
- * "data" is a const RIL_NetworkScanRequest *.
- * "response" is NULL
- *
- * Valid errors:
- *  SUCCESS
- *  RADIO_NOT_AVAILABLE
- *  DEVICE_IN_USE
- *  INTERNAL_ERR
- *  MODEM_ERR
- *  INVALID_ARGUMENTS
- *
- */
-#define RIL_REQUEST_START_NETWORK_SCAN4 146
-
-/**
  * RIL_REQUEST_GET_MODEM_STACK_STATUS
  *
  * Request status of a logical modem
@@ -6481,7 +6464,7 @@
  *  MODEM_ERR
  *
  */
-#define RIL_REQUEST_GET_MODEM_STACK_STATUS 147
+#define RIL_REQUEST_GET_MODEM_STACK_STATUS 146
 
 /**
  * @param info Response info struct containing response type, serial no. and error
@@ -6496,7 +6479,7 @@
  *   RadioError:REQUEST_NOT_SUPPORTED
  *   RadioError:NO_RESOURCES
  */
-#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP 148
+#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP 147
 
 /**
  * Callback of IRadio.setPreferredNetworkTypeBitmap(int, bitfield<RadioAccessFamily>)
@@ -6514,7 +6497,7 @@
  *   RadioError:REQUEST_NOT_SUPPORTED
  *   RadioError:NO_RESOURCES
  */
-#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP 149
+#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP 148
 
 /**
  * RIL_REQUEST_EMERGENCY_DIAL
@@ -6566,7 +6549,7 @@
  *  ABORTED
  *  INVALID_MODEM_STATE
  */
-#define RIL_REQUEST_EMERGENCY_DIAL 150
+#define RIL_REQUEST_EMERGENCY_DIAL 149
 
 /**
  * Specify which bands modem's background scan must act on.
@@ -6582,7 +6565,7 @@
  *  INTERNAL_ERR
  *
  */
-#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS 151
+#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS 150
 
 /**
  * RIL_REQUEST_ENABLE_MODEM
@@ -6595,58 +6578,11 @@
  *  MODEM_ERR
  *
  */
-#define RIL_REQUEST_ENABLE_MODEM 152
+#define RIL_REQUEST_ENABLE_MODEM 151
 
 /**
- * RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4
+ * RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA
  *
- * Set carrier restrictions. Expected modem behavior:
- *  If never receives this command:
- *  - Must allow all carriers
- *  Receives this command:
- *  - Only allow carriers specified in carriers. The restriction persists across power cycles
- *    and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is
- *    *not* allowed, modem must detach from the registered network and only keep emergency
- *    service, and notify Android SIM refresh reset with new SIM state being
- *    CardState:RESTRICTED. Emergency service must be enabled.
- *
- * "data" is const RIL_CarrierRestrictionsWithPriority *
- * A list of allowed carriers and possibly a list of excluded carriers with the priority and
- * multisim policy.
- *
- * Valid errors:
- *  RIL_E_SUCCESS
- *  RIL_E_INVALID_ARGUMENTS
- *  RIL_E_RADIO_NOT_AVAILABLE
- *  RIL_E_REQUEST_NOT_SUPPORTED
- *  INTERNAL_ERR
- *  NO_MEMORY
- *  NO_RESOURCES
- *  CANCELLED
- */
-#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4 153
-
-/**
- * RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4
- *
- * Gets the carrier restrictions.
- *
- * "data" is NULL
- *
- * "response" is const RIL_CarrierRestrictionsWithPriority *.
- *
- * Valid errors:
- *  RIL_E_SUCCESS
- *  RIL_E_RADIO_NOT_AVAILABLE
- *  RIL_E_REQUEST_NOT_SUPPORTED
- *  INTERNAL_ERR
- *  NO_MEMORY
- *  NO_RESOURCES
- *  CANCELLED
- */
-#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4 154
-
-/**
  * Sets the signal strength reporting criteria.
  *
  * The resulting reporting rules are the AND of all the supplied criteria. For each RAN
@@ -6679,7 +6615,7 @@
  *   RadioError:INVALID_ARGUMENTS
  *   RadioError:RADIO_NOT_AVAILABLE
  */
-#define RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5 155
+#define RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA 152
 
 /**
  * RIL_REQUEST_ENABLE_UICC_APPLICATIONS
@@ -6693,7 +6629,7 @@
  *  INTERNAL_ERR
  *  REQUEST_NOT_SUPPORTED
  */
-#define RIL_REQUEST_ENABLE_UICC_APPLICATIONS 156
+#define RIL_REQUEST_ENABLE_UICC_APPLICATIONS 153
 
 /**
  * RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED
@@ -6709,50 +6645,10 @@
  *  INTERNAL_ERR
  *  REQUEST_NOT_SUPPORTED
  */
-#define RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED 157
+#define RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED 154
 
 /**
- * Specify which bands modem's background scan must act on.
- * If specifyChannels is true, it only scans bands specified in specifiers.
- * If specifyChannels is false, it scans all bands.
- *
- * For example, CBRS is only on LTE band 48. By specifying this band,
- * modem saves more power.
- *
- * Valid errors:
- *  SUCCESS
- *  RADIO_NOT_AVAILABLE
- *  INTERNAL_ERR
- *  INVALID_ARGUMENTS
- *
- */
-#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5 158
-
-/**
- * RIL_REQUEST_START_NETWORK_SCAN5
- *
- * Starts a new network scan
- *
- * Request to start a network scan with specified radio access networks with frequency bands and/or
- * channels.
- *
- * "data" is a const RIL_NetworkScanRequest *.
- * "response" is NULL
- *
- * Valid errors:
- *  SUCCESS
- *  RADIO_NOT_AVAILABLE
- *  DEVICE_IN_USE
- *  INTERNAL_ERR
- *  MODEM_ERR
- *  INVALID_ARGUMENTS
- *
- */
-#define RIL_REQUEST_START_NETWORK_SCAN_1_5 159
-
-
-/**
- * RIL_REQUEST_SET_RADIO_POWER_1_5
+ * RIL_REQUEST_SET_RADIO_POWER
  *
  * Turn on or off radio power. It can also specify whether turning on radio power is to place an
  * emergency call and whether the call will be placed on this logical modem.
@@ -6763,8 +6659,7 @@
  *  INVALID_ARGUMENTS
  *
  */
-#define RIL_REQUEST_SET_RADIO_POWER_1_5 160
-
+#define RIL_REQUEST_SET_RADIO_POWER 155
 
 /**
  * RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION
@@ -6791,8 +6686,7 @@
  *  REQUEST_NOT_SUPPORTED
  */
 
-#define RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION 161
-
+#define RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION 156
 
 /**
  * RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE
@@ -6830,10 +6724,8 @@
  *  REQUEST_NOT_SUPPORTED
  *  MODE_NOT_SUPPORTED
  *  SIM_ABSENT
- *
  */
-#define RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE 162
-
+#define RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE 157
 
 /***********************************************************************/
 
diff --git a/guest/hals/ril/libril/ril_commands.h b/guest/hals/ril/libril/ril_commands.h
index 36c1fd0..852e28e 100644
--- a/guest/hals/ril/libril/ril_commands.h
+++ b/guest/hals/ril/libril/ril_commands.h
@@ -160,20 +160,15 @@
     {RIL_REQUEST_STOP_NETWORK_SCAN, radio_1_5::stopNetworkScanResponse},
     {RIL_REQUEST_START_KEEPALIVE, radio_1_5::startKeepaliveResponse},
     {RIL_REQUEST_STOP_KEEPALIVE, radio_1_5::stopKeepaliveResponse},
-    {RIL_REQUEST_START_NETWORK_SCAN4, radio_1_5::startNetworkScanResponse4},
     {RIL_REQUEST_GET_MODEM_STACK_STATUS, radio_1_5::getModemStackStatusResponse},
     {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_5::getPreferredNetworkTypeBitmapResponse},
     {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_5::setPreferredNetworkTypeBitmapResponse},
     {RIL_REQUEST_EMERGENCY_DIAL, radio_1_5::emergencyDialResponse},
     {RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, radio_1_5::setSystemSelectionChannelsResponse},
     {RIL_REQUEST_ENABLE_MODEM, radio_1_5::enableModemResponse},
-    {RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4, radio_1_5::setAllowedCarriersResponse4},
-    {RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4, radio_1_5::getAllowedCarriersResponse4},
-    {RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5, radio_1_5::setSignalStrengthReportingCriteriaResponse_1_5},
+    {RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA, radio_1_5::setSignalStrengthReportingCriteriaResponse},
     {RIL_REQUEST_ENABLE_UICC_APPLICATIONS, radio_1_5::enableUiccApplicationsResponse},
     {RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED, radio_1_5::areUiccApplicationsEnabledResponse},
-    {RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5, radio_1_5::setSystemSelectionChannelsResponse_1_5},
-    {RIL_REQUEST_START_NETWORK_SCAN_1_5, radio_1_5::startNetworkScanResponse_1_5},
-    {RIL_REQUEST_SET_RADIO_POWER_1_5, radio_1_5::setRadioPowerResponse_1_5},
+    {RIL_REQUEST_SET_RADIO_POWER, radio_1_5::setRadioPowerResponse},
     {RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, radio_1_5::supplySimDepersonalizationResponse},
     {RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE, radio_1_5::sendCdmaSmsExpectMoreResponse}
diff --git a/guest/hals/ril/libril/ril_service.cpp b/guest/hals/ril/libril/ril_service.cpp
index 69e33bb..7092037 100644
--- a/guest/hals/ril/libril/ril_service.cpp
+++ b/guest/hals/ril/libril/ril_service.cpp
@@ -170,10 +170,6 @@
 
     Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin);
 
-    Return<void> supplySimDepersonalization(int32_t serial,
-                                            ::android::hardware::radio::V1_5::PersoSubstate persoType,
-                                            const hidl_string& controlKey);
-
     Return<void> getCurrentCalls(int32_t serial);
 
     Return<void> dial(int32_t serial, const Dial& dialInfo);
@@ -351,8 +347,6 @@
 
     Return<void> sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms);
 
-    Return<void> sendCdmaSmsExpectMore(int32_t serial, const CdmaSmsMessage& sms);
-
     Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial,
             const CdmaSmsAck& smsAck);
 
@@ -567,6 +561,11 @@
     Return<void> getBarringInfo(int32_t serial);
     Return<void> getVoiceRegistrationState_1_5(int32_t serial);
     Return<void> getDataRegistrationState_1_5(int32_t serial);
+    Return<void> setNetworkSelectionModeManual_1_5(int32_t serial,
+            const hidl_string& operatorNumeric, V1_5::RadioAccessNetworks ran);
+    Return<void> sendCdmaSmsExpectMore(int32_t serial, const CdmaSmsMessage& sms);
+    Return<void> supplySimDepersonalization(int32_t serial, V1_5::PersoSubstate persoType,
+                                            const hidl_string& controlKey);
 };
 
 struct OemHookImpl : public IOemHook {
@@ -1041,17 +1040,6 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::supplySimDepersonalization(int32_t serial,
-                                                       ::android::hardware::radio::V1_5::PersoSubstate persoType,
-                                                       const hidl_string& controlKey) {
-#if VDBG
-    RLOGD("supplySimDepersonalization: serial %d", serial);
-#endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, true,
-            1, controlKey.c_str());
-    return Void();
-}
-
 Return<void> RadioImpl_1_5::getCurrentCalls(int32_t serial) {
 #if VDBG
     RLOGD("getCurrentCalls: serial %d", serial);
@@ -1191,22 +1179,6 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::getVoiceRegistrationState_1_5(int32_t serial) {
-#if VDBG
-    RLOGD("getVoiceRegistrationState: serial %d", serial);
-#endif
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE);
-    return Void();
-}
-
-Return<void> RadioImpl_1_5::getDataRegistrationState_1_5(int32_t serial) {
-#if VDBG
-    RLOGD("getDataRegistrationState: serial %d", serial);
-#endif
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE);
-    return Void();
-}
-
 Return<void> RadioImpl_1_5::getOperator(int32_t serial) {
 #if VDBG
     RLOGD("getOperator: serial %d", serial);
@@ -1216,7 +1188,9 @@
 }
 
 Return<void> RadioImpl_1_5::setRadioPower(int32_t serial, bool on) {
+#if VDBG
     RLOGD("setRadioPower: serial %d on %d", serial, on);
+#endif
     dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on));
     return Void();
 }
@@ -1919,22 +1893,6 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::sendCdmaSmsExpectMore(int32_t serial, const CdmaSmsMessage& sms) {
-#if VDBG
-    RLOGD("sendCdmaSms: serial %d", serial);
-#endif
-    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE);
-    if (pRI == NULL) {
-        return Void();
-    }
-
-    RIL_CDMA_SMS_Message rcsm = {};
-    constructCdmaSms(rcsm, sms);
-
-    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId);
-    return Void();
-}
-
 Return<void> RadioImpl_1_5::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) {
 #if VDBG
     RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial);
@@ -2921,7 +2879,6 @@
     }
 }
 
-
 Return<void> RadioImpl_1_5::setAllowedCarriers(int32_t serial, bool allAllowed,
                                            const CarrierRestrictions& carriers) {
 #if VDBG
@@ -2946,42 +2903,6 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::setAllowedCarriers_1_4(int32_t  serial,
-        const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& carriers,
-        ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy) {
-#if VDBG
-    RLOGD("setAllowedCarriers_1_4: serial %d", serial);
-#endif
-
-    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
-            RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4);
-    if (pRI == NULL) {
-        return Void();
-    }
-
-    // Prepare legacy structure (defined in IRadio 1.0) to re-use existing code.
-    RIL_CarrierRestrictions cr = {};
-    if (prepareCarrierRestrictions(cr, false, carriers.allowedCarriers,
-                                   carriers.excludedCarriers, pRI) < 0) {
-        return Void();
-    }
-    // Copy the legacy structure into the new structure (defined in IRadio 1.4)
-    RIL_CarrierRestrictionsWithPriority crExt = {};
-    crExt.len_allowed_carriers = cr.len_allowed_carriers;
-    crExt.allowed_carriers = cr.allowed_carriers;
-    crExt.len_excluded_carriers = cr.len_excluded_carriers;
-    crExt.excluded_carriers = cr.excluded_carriers;
-    crExt.allowedCarriersPrioritized = BOOL_TO_INT(carriers.allowedCarriersPrioritized);
-    crExt.multiSimPolicy = (RIL_SimLockMultiSimPolicy)multiSimPolicy;
-
-    CALL_ONREQUEST(pRI->pCI->requestNumber, &crExt,
-                   sizeof(RIL_CarrierRestrictionsWithPriority), pRI, mSlotId);
-
-    freeCarrierRestrictions(cr);
-
-    return Void();
-}
-
 Return<void> RadioImpl_1_5::getAllowedCarriers(int32_t serial) {
 #if VDBG
     RLOGD("getAllowedCarriers: serial %d", serial);
@@ -2990,14 +2911,6 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::getAllowedCarriers_1_4(int32_t serial) {
-#if VDBG
-    RLOGD("getAllowedCarriers_1_4: serial %d", serial);
-#endif
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4);
-    return Void();
-}
-
 Return<void> RadioImpl_1_5::sendDeviceState(int32_t serial, DeviceStateType deviceStateType,
                                         bool state) {
 #if VDBG
@@ -3150,6 +3063,7 @@
     return Void();
 }
 
+// Methods from ::android::hardware::radio::V1_2::IRadio follow.
 int prepareNetworkScanRequest_1_2(RIL_NetworkScanRequest &scan_request,
     const ::android::hardware::radio::V1_2::NetworkScanRequest& request,
     RequestInfo *pRI) {
@@ -3238,99 +3152,6 @@
     return 0;
 }
 
-int prepareNetworkScanRequest_1_5(RIL_NetworkScanRequest &scan_request,
-    const ::android::hardware::radio::V1_5::NetworkScanRequest& request,
-    RequestInfo *pRI) {
-
-    scan_request.type = (RIL_ScanType) request.type;
-    scan_request.interval = request.interval;
-    scan_request.specifiers_length = request.specifiers.size();
-
-    int intervalLow = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MIN);
-    int intervalHigh = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MAX);
-    int maxSearchTimeLow =
-        static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MIN);
-    int maxSearchTimeHigh =
-        static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MAX);
-    int incrementalResultsPeriodicityRangeLow =
-        static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MIN);
-    int incrementalResultsPeriodicityRangeHigh =
-        static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MAX);
-    uint maxSpecifierSize =
-        static_cast<uint>(::android::hardware::radio::V1_2::RadioConst
-            ::RADIO_ACCESS_SPECIFIER_MAX_SIZE);
-
-    if (request.interval < intervalLow || request.interval > intervalHigh) {
-        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-        return -1;
-    }
-    // If defined, must fall in correct range.
-    if (request.maxSearchTime != 0
-        && (request.maxSearchTime < maxSearchTimeLow
-            || request.maxSearchTime > maxSearchTimeHigh)) {
-        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-        return -1;
-    }
-    if (request.maxSearchTime != 0
-        && (request.incrementalResultsPeriodicity < incrementalResultsPeriodicityRangeLow
-            || request.incrementalResultsPeriodicity > incrementalResultsPeriodicityRangeHigh
-            || request.incrementalResultsPeriodicity > request.maxSearchTime)) {
-        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-        return -1;
-    }
-    if (request.specifiers.size() == 0 || request.specifiers.size() > maxSpecifierSize) {
-        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-        return -1;
-    }
-
-    for (size_t i = 0; i < request.specifiers.size(); ++i) {
-        if (request.specifiers[i].bands.geranBands().size() > MAX_BANDS ||
-            request.specifiers[i].bands.utranBands().size() > MAX_BANDS ||
-            request.specifiers[i].bands.eutranBands().size() > MAX_BANDS ||
-            request.specifiers[i].bands.ngranBands().size() > MAX_BANDS ||
-            request.specifiers[i].channels.size() > MAX_CHANNELS) {
-            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-            return -1;
-        }
-        const V1_5::RadioAccessSpecifier& ras_from = request.specifiers[i];
-        RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i];
-
-        ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork;
-        ras_to.channels_length = ras_from.channels.size();
-
-        std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels);
-        const std::vector<uint32_t> * bands = nullptr;
-        switch (request.specifiers[i].radioAccessNetwork) {
-            case V1_5::RadioAccessNetworks::GERAN:
-                ras_to.bands_length = ras_from.bands.geranBands().size();
-                bands = (std::vector<uint32_t> *) &ras_from.bands;
-                break;
-            case V1_5::RadioAccessNetworks::UTRAN:
-                ras_to.bands_length = ras_from.bands.utranBands().size();
-                bands = (std::vector<uint32_t> *) &ras_from.bands;
-                break;
-            case V1_5::RadioAccessNetworks::EUTRAN:
-                ras_to.bands_length = ras_from.bands.eutranBands().size();
-                bands = (std::vector<uint32_t> *) &ras_from.bands;
-                break;
-            case V1_5::RadioAccessNetworks::NGRAN:
-                ras_to.bands_length = ras_from.bands.ngranBands().size();
-                bands = (std::vector<uint32_t> *) &ras_from.bands;
-                break;
-            default:
-                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
-                return -1;
-        }
-        // safe to copy to geran_bands because it's a union member
-        for (size_t idx = 0; idx < ras_to.bands_length; ++idx) {
-            ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx];
-        }
-    }
-
-    return 0;
-}
-
-// Methods from ::android::hardware::radio::V1_2::IRadio follow.
 Return<void> RadioImpl_1_5::startNetworkScan_1_2(int32_t serial,
         const ::android::hardware::radio::V1_2::NetworkScanRequest& request) {
 #if VDBG
@@ -3342,10 +3163,6 @@
         return Void();
     }
 
-    // TODO: implement checks for new fields.
-    // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and
-    // mccMncs, could add more validations using request2 here.
-
     RIL_NetworkScanRequest scan_request = {};
 
     if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) {
@@ -3458,6 +3275,50 @@
 }
 
 // Methods from ::android::hardware::radio::V1_4::IRadio follow.
+Return<void> RadioImpl_1_5::setAllowedCarriers_1_4(int32_t  serial,
+        const V1_4::CarrierRestrictionsWithPriority& carriers,
+        V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+#if VDBG
+    RLOGD("setAllowedCarriers_1_4: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_CARRIER_RESTRICTIONS);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    // Prepare legacy structure (defined in IRadio 1.0) to re-use existing code.
+    RIL_CarrierRestrictions cr = {};
+    if (prepareCarrierRestrictions(cr, false, carriers.allowedCarriers, carriers.excludedCarriers,
+            pRI) < 0) {
+        return Void();
+    }
+    // Copy the legacy structure into the new structure (defined in IRadio 1.4)
+    RIL_CarrierRestrictionsWithPriority crExt = {};
+    crExt.len_allowed_carriers = cr.len_allowed_carriers;
+    crExt.allowed_carriers = cr.allowed_carriers;
+    crExt.len_excluded_carriers = cr.len_excluded_carriers;
+    crExt.excluded_carriers = cr.excluded_carriers;
+    crExt.allowedCarriersPrioritized = BOOL_TO_INT(carriers.allowedCarriersPrioritized);
+    crExt.multiSimPolicy = (RIL_SimLockMultiSimPolicy)multiSimPolicy;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &crExt, sizeof(RIL_CarrierRestrictionsWithPriority),
+            pRI, mSlotId);
+
+    freeCarrierRestrictions(cr);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_5::getAllowedCarriers_1_4(int32_t serial) {
+#if VDBG
+    RLOGD("getAllowedCarriers_1_4: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS);
+    return Void();
+}
+
 Return<void> RadioImpl_1_5::setupDataCall_1_4(int32_t serial ,
         ::android::hardware::radio::V1_4::AccessNetwork /* accessNetwork */,
         const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo,
@@ -3602,22 +3463,18 @@
     RLOGD("startNetworkScan_1_4: serial %d", serial);
 #endif
 
-    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN4);
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
     if (pRI == NULL) {
         return Void();
     }
 
-    // TODO: implement checks for new fields.
-    // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and
-    // mccMncs, could add more validations using request2 here.
-
     RIL_NetworkScanRequest scan_request = {};
 
     if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) {
         return Void();
     }
 
-    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN4, &scan_request, sizeof(scan_request), pRI,
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI,
             mSlotId);
 
     return Void();
@@ -3673,7 +3530,7 @@
     RLOGD("setRadioPower_1_5: serial %d powerOn %d forEmergency %d preferredForEmergencyCall %d",
         serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
 #endif
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_RADIO_POWER_1_5);
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_RADIO_POWER);
     return Void();
 }
 
@@ -3685,37 +3542,134 @@
     return Void();
 }
 
-Return<void> RadioImpl_1_5::setSystemSelectionChannels_1_5(int32_t serial, bool /* specifyChannels */,
-        const hidl_vec<::android::hardware::radio::V1_5::RadioAccessSpecifier>& /* specifiers */) {
+Return<void> RadioImpl_1_5::getVoiceRegistrationState_1_5(int32_t serial) {
+#if VDBG
+    RLOGD("getVoiceRegistrationState: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_5::getDataRegistrationState_1_5(int32_t serial) {
+#if VDBG
+    RLOGD("getDataRegistrationState: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_5::setSystemSelectionChannels_1_5(int32_t serial,
+        bool /* specifyChannels */, const hidl_vec<V1_5::RadioAccessSpecifier>& /* specifiers */) {
 #if VDBG
     RLOGD("setSystemSelectionChannels_1_5: serial %d", serial);
 #endif
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5);
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS);
     return Void();
 }
 
+int prepareNetworkScanRequest_1_5(RIL_NetworkScanRequest &scan_request,
+        const V1_5::NetworkScanRequest& request, RequestInfo *pRI) {
+    scan_request.type = (RIL_ScanType) request.type;
+    scan_request.interval = request.interval;
+    scan_request.specifiers_length = request.specifiers.size();
+
+    int intervalLow = static_cast<int>(V1_2::ScanIntervalRange::MIN);
+    int intervalHigh = static_cast<int>(V1_2::ScanIntervalRange::MAX);
+    int maxSearchTimeLow = static_cast<int>(V1_2::MaxSearchTimeRange::MIN);
+    int maxSearchTimeHigh = static_cast<int>(V1_2::MaxSearchTimeRange::MAX);
+    int incrementalResultsPeriodicityRangeLow =
+            static_cast<int>(V1_2::IncrementalResultsPeriodicityRange::MIN);
+    int incrementalResultsPeriodicityRangeHigh =
+            static_cast<int>(V1_2::IncrementalResultsPeriodicityRange::MAX);
+    uint maxSpecifierSize = static_cast<uint>(V1_2::RadioConst::RADIO_ACCESS_SPECIFIER_MAX_SIZE);
+
+    if (request.interval < intervalLow || request.interval > intervalHigh) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    // If defined, must fall in correct range.
+    if (request.maxSearchTime != 0 && (request.maxSearchTime < maxSearchTimeLow
+            || request.maxSearchTime > maxSearchTimeHigh)) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    if (request.maxSearchTime != 0
+            && (request.incrementalResultsPeriodicity < incrementalResultsPeriodicityRangeLow
+            || request.incrementalResultsPeriodicity > incrementalResultsPeriodicityRangeHigh
+            || request.incrementalResultsPeriodicity > request.maxSearchTime)) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    if (request.specifiers.size() == 0 || request.specifiers.size() > maxSpecifierSize) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+
+    for (size_t i = 0; i < request.specifiers.size(); ++i) {
+        if (request.specifiers[i].bands.geranBands().size() > MAX_BANDS
+                || request.specifiers[i].bands.utranBands().size() > MAX_BANDS
+                || request.specifiers[i].bands.eutranBands().size() > MAX_BANDS
+                || request.specifiers[i].bands.ngranBands().size() > MAX_BANDS
+                || request.specifiers[i].channels.size() > MAX_CHANNELS) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            return -1;
+        }
+        const V1_5::RadioAccessSpecifier& ras_from = request.specifiers[i];
+        RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i];
+
+        ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork;
+        ras_to.channels_length = ras_from.channels.size();
+
+        std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels);
+        const std::vector<uint32_t> * bands = nullptr;
+        switch (request.specifiers[i].radioAccessNetwork) {
+            case V1_5::RadioAccessNetworks::GERAN:
+                ras_to.bands_length = ras_from.bands.geranBands().size();
+                bands = (std::vector<uint32_t> *) &ras_from.bands;
+                break;
+            case V1_5::RadioAccessNetworks::UTRAN:
+                ras_to.bands_length = ras_from.bands.utranBands().size();
+                bands = (std::vector<uint32_t> *) &ras_from.bands;
+                break;
+            case V1_5::RadioAccessNetworks::EUTRAN:
+                ras_to.bands_length = ras_from.bands.eutranBands().size();
+                bands = (std::vector<uint32_t> *) &ras_from.bands;
+                break;
+            case V1_5::RadioAccessNetworks::NGRAN:
+                ras_to.bands_length = ras_from.bands.ngranBands().size();
+                bands = (std::vector<uint32_t> *) &ras_from.bands;
+                break;
+            default:
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return -1;
+        }
+        // safe to copy to geran_bands because it's a union member
+        for (size_t idx = 0; idx < ras_to.bands_length; ++idx) {
+            ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx];
+        }
+    }
+
+    return 0;
+}
+
 Return<void> RadioImpl_1_5::startNetworkScan_1_5(int32_t serial,
         const ::android::hardware::radio::V1_5::NetworkScanRequest& request) {
 #if VDBG
     RLOGD("startNetworkScan_1_5: serial %d", serial);
 #endif
 
-    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN_1_5);
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
     if (pRI == NULL) {
         return Void();
     }
 
-    // TODO: implement checks for new fields.
-    // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and
-    // mccMncs, could add more validations using request2 here.
-
     RIL_NetworkScanRequest scan_request = {};
 
     if (prepareNetworkScanRequest_1_5(scan_request, request, pRI) < 0) {
         return Void();
     }
 
-    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN_1_5, &scan_request, sizeof(scan_request), pRI,
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI,
             mSlotId);
 
     return Void();
@@ -3836,6 +3790,42 @@
     return Void();
 }
 
+Return<void> RadioImpl_1_5::setNetworkSelectionModeManual_1_5(int32_t serial,
+        const hidl_string& operatorNumeric, V1_5::RadioAccessNetworks ran) {
+#if VDBG
+    RLOGD("setNetworkSelectionModeManual_1_5: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL);
+    return Void();
+}
+
+Return<void> RadioImpl_1_5::sendCdmaSmsExpectMore(int32_t serial, const CdmaSmsMessage& sms) {
+#if VDBG
+    RLOGD("sendCdmaSmsExpectMore: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CDMA_SMS_Message rcsm = {};
+    constructCdmaSms(rcsm, sms);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_5::supplySimDepersonalization(int32_t serial,
+        V1_5::PersoSubstate persoType, const hidl_string& controlKey) {
+#if VDBG
+    RLOGD("supplySimDepersonalization: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, true, 1,
+            controlKey.c_str());
+    return Void();
+}
+
 // OEM hook methods:
 Return<void> OemHookImpl::setResponseFunctions(
         const ::android::sp<IOemHookResponse>& oemHookResponseParam,
@@ -4164,37 +4154,6 @@
     return 0;
 }
 
-int radio_1_5::supplySimDepersonalizationResponse(int slotId,
-                                                 int responseType, int serial, RIL_Errno e,
-                                                 void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("supplySimDepersonalizationResponse: serial %d", serial);
-#endif
-
-    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        int persoType = -1, remainingRetries = -1;
-        int numInts = responseLen / sizeof(int);
-        if (response == NULL || numInts != 2) {
-            RLOGE("getClirResponse Invalid response: NULL");
-            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
-        } else {
-            int *pInt = (int *) response;
-            persoType = pInt[0];
-            remainingRetries = pInt[1];
-        }
-        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5->
-                supplySimDepersonalizationResponse(responseInfo, (::android::hardware::radio::V1_5::PersoSubstate) persoType,
-                                                   remainingRetries);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("supplySimDepersonalizationResponse: radioService[%d]->mRadioResponseV1_5 == "
-                "NULL", slotId);
-    }
-
-    return 0;
-}
-
 int radio_1_5::getCurrentCallsResponse(int slotId,
                                   int responseType, int serial, RIL_Errno e,
                                   void *response, size_t responseLen) {
@@ -4956,17 +4915,22 @@
 int radio_1_5::setRadioPowerResponse(int slotId,
                                 int responseType, int serial, RIL_Errno e, void *response,
                                 size_t responseLen) {
+#if VDBG
     RLOGD("setRadioPowerResponse: serial %d", serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponse != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse(
-                responseInfo);
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->setRadioPowerResponse_1_5(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponse
+                ->setRadioPowerResponse(responseInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
-        RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL",
-                slotId);
+        RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL", slotId);
     }
 
     return 0;
@@ -5569,13 +5533,16 @@
 #if VDBG
     RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial);
 #endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponse != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse(
-                responseInfo);
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->setNetworkSelectionModeManualResponse_1_5(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponse
+                ->setNetworkSelectionModeManualResponse(responseInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
         RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse "
@@ -6399,28 +6366,6 @@
     return 0;
 }
 
-int radio_1_5::sendCdmaSmsExpectMoreResponse(int slotId,
-                              int responseType, int serial, RIL_Errno e, void *response,
-                              size_t responseLen) {
-#if VDBG
-    RLOGD("sendCdmaSmsExpectMoreResponse: serial %d", serial);
-#endif
-
-    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
-                responseLen);
-
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_5->sendCdmaSmsExpectMoreResponse(responseInfo, result);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("sendCdmaSmsExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId);
-    }
-
-    return 0;
-}
-
 int radio_1_5::acknowledgeLastIncomingCdmaSmsResponse(int slotId,
                                                  int responseType, int serial, RIL_Errno e,
                                                  void *response, size_t responseLen) {
@@ -7604,36 +7549,19 @@
 #if VDBG
     RLOGD("setAllowedCarriersResponse: serial %d", serial);
 #endif
-
-    if (radioService[slotId]->mRadioResponse != NULL) {
-        RadioResponseInfo responseInfo = {};
-        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo,
-                ret);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
-                slotId);
-    }
-
-    return 0;
-}
-
-int radio_1_5::setAllowedCarriersResponse4(int slotId, int responseType, int serial, RIL_Errno e,
-                                    void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("setAllowedCarriersResponse4: serial %d", serial);
-#endif
+    RadioResponseInfo responseInfo = {};
 
     if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_4->setAllowedCarriersResponse_1_4(responseInfo);
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4
+                ->setAllowedCarriersResponse_1_4(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse
+                ->setAllowedCarriersResponse(responseInfo, ret);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
-        RLOGE("setAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+        RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", slotId);
     }
 
     return 0;
@@ -7673,10 +7601,48 @@
 #if VDBG
     RLOGD("getAllowedCarriersResponse: serial %d", serial);
 #endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponse != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        V1_4::CarrierRestrictionsWithPriority carrierInfo = {};
+        V1_4::SimLockMultiSimPolicy multiSimPolicy =
+                V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+        bool allAllowed = true;
+
+        if (response == NULL) {
+#if VDBG
+            RLOGD("getAllowedCarriersResponse response is NULL: all allowed");
+#endif
+            carrierInfo.allowedCarriers.resize(0);
+            carrierInfo.excludedCarriers.resize(0);
+            carrierInfo.allowedCarriersPrioritized = false;
+        } else if (responseLen != sizeof(RIL_CarrierRestrictionsWithPriority)) {
+            RLOGE("getAllowedCarriersResponse Invalid response");
+            if (e == RIL_E_SUCCESS) {
+                responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
+        } else {
+            RIL_CarrierRestrictionsWithPriority *pCrExt =
+                    (RIL_CarrierRestrictionsWithPriority *)response;
+
+            // Convert into the structure used in IRadio 1.0 to re-use existing code
+            RIL_CarrierRestrictions cr = {};
+            cr.len_allowed_carriers = pCrExt->len_allowed_carriers;
+            cr.len_excluded_carriers = pCrExt->len_excluded_carriers;
+            cr.allowed_carriers = pCrExt->allowed_carriers;
+            cr.excluded_carriers = pCrExt->excluded_carriers;
+            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers,
+                    carrierInfo.excludedCarriers, allAllowed, &cr);
+
+            carrierInfo.allowedCarriersPrioritized = (bool)pCrExt->allowedCarriersPrioritized;
+            multiSimPolicy = (V1_4::SimLockMultiSimPolicy)pCrExt->multiSimPolicy;
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4
+                ->getAllowedCarriersResponse_1_4(responseInfo, carrierInfo, multiSimPolicy);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
         CarrierRestrictions carrierInfo = {};
         bool allAllowed = true;
         if (response == NULL) {
@@ -7692,70 +7658,15 @@
             }
         } else {
             RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response;
-            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, pCr);
+            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers,
+                    carrierInfo.excludedCarriers, allAllowed, pCr);
         }
 
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo,
-                allAllowed, carrierInfo);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse
+                ->getAllowedCarriersResponse(responseInfo, allAllowed, carrierInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
-        RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
-                slotId);
-    }
-
-    return 0;
-}
-
-int radio_1_5::getAllowedCarriersResponse4(int slotId,
-                                      int responseType, int serial, RIL_Errno e,
-                                      void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("getAllowedCarriersResponse4: serial %d", serial);
-#endif
-
-    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-
-        ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierInfo = {};
-        ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy =
-                ::android::hardware::radio::V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
-        bool allAllowed = true;
-
-        if (response == NULL) {
-#if VDBG
-            RLOGD("getAllowedCarriersResponse4 response is NULL: all allowed");
-#endif
-            carrierInfo.allowedCarriers.resize(0);
-            carrierInfo.excludedCarriers.resize(0);
-            carrierInfo.allowedCarriersPrioritized = false;
-        } else if (responseLen != sizeof(RIL_CarrierRestrictionsWithPriority)) {
-            RLOGE("getAllowedCarriersResponse4 Invalid response");
-            if (e == RIL_E_SUCCESS) {
-                responseInfo.error = RadioError::INVALID_RESPONSE;
-            }
-        } else {
-            RIL_CarrierRestrictionsWithPriority *pCrExt = (RIL_CarrierRestrictionsWithPriority *)response;
-
-            // Convert into the structure used in IRadio 1.0 to re-use existing code
-            RIL_CarrierRestrictions cr = {};
-            cr.len_allowed_carriers = pCrExt->len_allowed_carriers;
-            cr.len_excluded_carriers = pCrExt->len_excluded_carriers;
-            cr.allowed_carriers = pCrExt->allowed_carriers;
-            cr.excluded_carriers = pCrExt->excluded_carriers;
-            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, &cr);
-
-            carrierInfo.allowedCarriersPrioritized = (bool)pCrExt->allowedCarriersPrioritized;
-            multiSimPolicy = (::android::hardware::radio::V1_4::SimLockMultiSimPolicy)pCrExt->multiSimPolicy;
-        }
-
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_4->getAllowedCarriersResponse_1_4(responseInfo,
-                carrierInfo, multiSimPolicy);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("getAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+        RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", slotId);
     }
 
     return 0;
@@ -7804,16 +7715,19 @@
 #if VDBG
     RLOGD("setIndicationFilterResponse: serial %d", serial);
 #endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponse != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo);
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->setIndicationFilterResponse_1_5(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponse
+                ->setIndicationFilterResponse(responseInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
-        RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL",
-                slotId);
+        RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL", slotId);
     }
 
     return 0;
@@ -7853,33 +7767,23 @@
 #if VDBG
     RLOGD("startNetworkScanResponse: serial %d", serial);
 #endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse(responseInfo);
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->startNetworkScanResponse_1_5(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4
+                ->startNetworkScanResponse_1_4(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponseV1_2 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_2
+                ->startNetworkScanResponse(responseInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
     } else {
-        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
-    }
-
-    return 0;
-}
-
-int radio_1_5::startNetworkScanResponse4(int slotId, int responseType, int serial, RIL_Errno e,
-                                    void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("startNetworkScanResponse4: serial %d", serial);
-#endif
-    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse_1_4(responseInfo);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponse == NULL", slotId);
     }
 
     return 0;
@@ -8088,40 +7992,48 @@
 int radio_1_5::setSystemSelectionChannelsResponse(int slotId, int responseType, int serial,
                                         RIL_Errno e, void* /* response */, size_t responseLen) {
 #if VDBG
-    RLOGD("%s(): %d", __FUNCTION__, serial);
+    RLOGD("setSystemSelectionChannelsResponse: serial %d", serial);
 #endif
     RadioResponseInfo responseInfo = {};
     populateResponseInfo(responseInfo, serial, responseType, e);
 
-    // If we don't have a radio service, there's nothing we can do
-    if (radioService[slotId]->mRadioResponseV1_3 == NULL) {
-        RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId);
-        return 0;
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->setSystemSelectionChannelsResponse_1_5(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponseV1_3 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_3
+                ->setSystemSelectionChannelsResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setSystemSelectionChannelsResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
     }
 
-    Return<void> retStatus =
-            radioService[slotId]->mRadioResponseV1_3->setSystemSelectionChannelsResponse(
-            responseInfo);
-    radioService[slotId]->checkReturnStatus(retStatus);
     return 0;
 }
 
-int radio_1_5::setSignalStrengthReportingCriteriaResponse_1_5(int slotId, int responseType,
-                                        int serial, RIL_Errno e, void* /* response */,
-                                        size_t responseLen) {
+int radio_1_5::setSignalStrengthReportingCriteriaResponse(int slotId, int responseType, int serial,
+                                        RIL_Errno e, void* /* response */, size_t responseLen) {
 #if VDBG
-    RLOGD("%s(): %d", __FUNCTION__, serial);
+    RLOGD("setSignalStrengthReportingCriteriaResponse: serial %d", serial);
 #endif
     RadioResponseInfo responseInfo = {};
     populateResponseInfo(responseInfo, serial, responseType, e);
 
-    if (radioService[slotId]->mRadioResponseV1_5 == NULL) {
-        RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId);
-        Return<void> retStatus =
-                radioService[slotId]->mRadioResponseV1_5->setSignalStrengthReportingCriteriaResponse_1_5(
-                responseInfo);
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->setSignalStrengthReportingCriteriaResponse_1_5(responseInfo);
         radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponseV1_2 != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_2
+                ->setSignalStrengthReportingCriteriaResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setSignalStrengthReportingCriteriaResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
     }
+
     return 0;
 }
 
@@ -8174,87 +8086,6 @@
     return 0;
 }
 
-int radio_1_5::setSystemSelectionChannelsResponse_1_5(int slotId, int responseType, int serial,
-                                        RIL_Errno e, void* /* response */, size_t responseLen) {
-#if VDBG
-    RLOGD("%s(): %d", __FUNCTION__, serial);
-#endif
-    RadioResponseInfo responseInfo = {};
-    populateResponseInfo(responseInfo, serial, responseType, e);
-
-    // If we don't have a radio service, there's nothing we can do
-    if (radioService[slotId]->mRadioResponseV1_5 == NULL) {
-        RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId);
-        return 0;
-    }
-
-    Return<void> retStatus =
-            radioService[slotId]->mRadioResponseV1_5->setSystemSelectionChannelsResponse_1_5(
-            responseInfo);
-    radioService[slotId]->checkReturnStatus(retStatus);
-    return 0;
-}
-
-int radio_1_5::startNetworkScanResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e,
-                                    void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("startNetworkScanResponse_1_5: serial %d", serial);
-#endif
-    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_5->startNetworkScanResponse_1_5(responseInfo);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_5 == NULL", slotId);
-    }
-    return 0;
-}
-
-int radio_1_5::setRadioPowerResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e,
-                                         void* /* response */, size_t responseLen) {
-#if VDBG
-    RLOGD("%s(): %d", __FUNCTION__, serial);
-#endif
-    RadioResponseInfo responseInfo = {};
-    populateResponseInfo(responseInfo, serial, responseType, e);
-
-    // If we don't have a radio service, there's nothing we can do
-    if (radioService[slotId]->mRadioResponseV1_5 == NULL) {
-        RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId);
-        return 0;
-    }
-
-    Return<void> retStatus =
-            radioService[slotId]->mRadioResponseV1_5->setRadioPowerResponse_1_5(
-            responseInfo);
-    radioService[slotId]->checkReturnStatus(retStatus);
-    return 0;
-}
-
-int radio_1_5::setIndicationFilterResponse_1_5(int slotId,
-                              int responseType, int serial, RIL_Errno e,
-                              void *response, size_t responselen) {
-#if VDBG
-    RLOGD("setIndicationFilterResponse_1_5: serial %d", serial);
-#endif
-
-    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
-        RadioResponseInfo responseInfo = {};
-        populateResponseInfo(responseInfo, serial, responseType, e);
-        Return<void> retStatus
-                = radioService[slotId]->mRadioResponseV1_5->
-                        setIndicationFilterResponse_1_5(responseInfo);
-        radioService[slotId]->checkReturnStatus(retStatus);
-    } else {
-        RLOGE("setIndicationFilterResponse_1_5: radioService[%d]->mRadioResponse == NULL",
-                slotId);
-    }
-
-    return 0;
-}
-
 int radio_1_5::getBarringInfoResponse(int slotId,
                               int responseType, int serial, RIL_Errno e,
                               void *response, size_t responselen) {
@@ -8278,6 +8109,57 @@
     return 0;
 }
 
+int radio_1_5::sendCdmaSmsExpectMoreResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendCdmaSmsExpectMoreResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->sendCdmaSmsExpectMoreResponse(responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendCdmaSmsExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_5::supplySimDepersonalizationResponse(int slotId, int responseType, int serial,
+                                                  RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplySimDepersonalizationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int persoType = -1, remainingRetries = -1;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || numInts != 2) {
+            RLOGE("getClirResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            persoType = pInt[0];
+            remainingRetries = pInt[1];
+        }
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_5
+                ->supplySimDepersonalizationResponse(responseInfo, (V1_5::PersoSubstate) persoType,
+                remainingRetries);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplySimDepersonalizationResponse: radioService[%d]->mRadioResponseV1_5 == "
+                "NULL", slotId);
+    }
+
+    return 0;
+}
+
 /***************************************************************************************************
  * INDICATION FUNCTIONS
  * The below function handle unsolicited messages coming from the Radio
diff --git a/guest/hals/ril/libril/ril_service.h b/guest/hals/ril/libril/ril_service.h
index 23e6ca9..972764f 100644
--- a/guest/hals/ril/libril/ril_service.h
+++ b/guest/hals/ril/libril/ril_service.h
@@ -54,10 +54,6 @@
                                           int responseType, int serial, RIL_Errno e,
                                           void *response, size_t responselen);
 
-int supplySimDepersonalizationResponse(int slotId,
-                                          int responseType, int serial, RIL_Errno e,
-                                          void *response, size_t responselen);
-
 int getCurrentCallsResponse(int slotId,
                            int responseType, int serial, RIL_Errno e, void *response,
                            size_t responselen);
@@ -207,14 +203,6 @@
                              int responseType, int serial, RIL_Errno e, void *response,
                              size_t responselen);
 
-int startNetworkScanResponse4(int slotId,
-                             int responseType, int serial, RIL_Errno e, void *response,
-                             size_t responselen);
-
-int startNetworkScanResponse_1_5(int slotId,
-                             int responseType, int serial, RIL_Errno e, void *response,
-                             size_t responselen);
-
 int stopNetworkScanResponse(int slotId,
                             int responseType, int serial, RIL_Errno e, void *response,
                             size_t responselen);
@@ -351,10 +339,6 @@
                        int responseType, int serial, RIL_Errno e, void *response,
                        size_t responselen);
 
-int sendCdmaSmsExpectMoreResponse(int slotId,
-                       int responseType, int serial, RIL_Errno e, void *response,
-                       size_t responselen);
-
 int acknowledgeLastIncomingCdmaSmsResponse(int slotId,
                                           int responseType, int serial, RIL_Errno e, void *response,
                                           size_t responselen);
@@ -780,23 +764,8 @@
                                int responseType, int serial, RIL_Errno e,
                                void *response, size_t responseLen);
 
-int setSystemSelectionChannelsResponse_1_5(int slotId,
-                               int responseType, int serial, RIL_Errno e,
-                               void *response, size_t responseLen);
-
-int setAllowedCarriersResponse4(int slotId,
-                                int responseType, int serial, RIL_Errno e,
-                                void *response,
-                                size_t responselen);
-
-int getAllowedCarriersResponse4(int slotId,
-                                int responseType, int serial, RIL_Errno e,
-                                void *response,
-                                size_t responselen);
-
-int setSignalStrengthReportingCriteriaResponse_1_5(int slotId,
-                          int responseType, int serial, RIL_Errno e,
-                          void *response, size_t responselen);
+int setSignalStrengthReportingCriteriaResponse(int slotId, int responseType, int serial,
+                                               RIL_Errno e, void *response, size_t responselen);
 
 int enableUiccApplicationsResponse(int slotId,
                                  int responseType, int serial, RIL_Errno e,
@@ -806,14 +775,17 @@
                                      int responseType, int serial, RIL_Errno e,
                                      void *response, size_t responselen);
 
-int setRadioPowerResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e,
-                              void *response, size_t responselen);
+int setRadioPowerResponse(int slotId, int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
 
-int setIndicationFilterResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e,
-                              void *response, size_t responselen);
+int getBarringInfoResponse(int slotId, int responseType, int serial, RIL_Errno e, void *response,
+                           size_t responselen);
 
-int getBarringInfoResponse(int slotId, int responseType, int serial, RIL_Errno e,
-                              void *response, size_t responselen);
+int sendCdmaSmsExpectMoreResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responselen);
+
+int supplySimDepersonalizationResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responselen);
 
 pthread_rwlock_t * getRadioServiceRwlock(int slotId);
 
diff --git a/guest/monitoring/dumpstate_ext/Android.bp b/guest/monitoring/dumpstate_ext/Android.bp
index ba3320c..e679dc4 100644
--- a/guest/monitoring/dumpstate_ext/Android.bp
+++ b/guest/monitoring/dumpstate_ext/Android.bp
@@ -14,13 +14,14 @@
 // limitations under the License.
 
 cc_binary {
-    name: "android.hardware.dumpstate@1.0-service.cuttlefish",
+    name: "android.hardware.dumpstate@1.1-service.cuttlefish",
     srcs: [
         "dumpstate_device.cpp",
         "service.cpp",
     ],
     shared_libs: [
         "android.hardware.dumpstate@1.0",
+        "android.hardware.dumpstate@1.1",
         "libbase",
         "libcutils",
         "libdumpstateutil",
@@ -33,7 +34,7 @@
     ],
     relative_install_path: "hw",
     init_rc: [
-        "android.hardware.dumpstate@1.0-service.cuttlefish.rc",
+        "android.hardware.dumpstate@1.1-service.cuttlefish.rc",
     ],
     defaults: ["cuttlefish_guest_only"]
 }
diff --git a/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc b/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc
deleted file mode 100644
index ad68f35..0000000
--- a/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service dumpstate-1-0 /vendor/bin/hw/android.hardware.dumpstate@1.0-service.cuttlefish
-    class hal
-    user system
-    group system
diff --git a/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.1-service.cuttlefish.rc b/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.1-service.cuttlefish.rc
new file mode 100644
index 0000000..3fb31e3
--- /dev/null
+++ b/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.1-service.cuttlefish.rc
@@ -0,0 +1,4 @@
+service dumpstate-1-1 /vendor/bin/hw/android.hardware.dumpstate@1.1-service.cuttlefish
+    class hal
+    user system
+    group system
diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp b/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
index d8481c7..48bc9d2 100644
--- a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
+++ b/guest/monitoring/dumpstate_ext/dumpstate_device.cpp
@@ -15,19 +15,26 @@
  */
 #include "guest/monitoring/dumpstate_ext/dumpstate_device.h"
 
-#include <log/log.h>
 #include <DumpstateUtil.h>
+#include <log/log.h>
 
 using android::os::dumpstate::DumpFileToFd;
 
 namespace android {
 namespace hardware {
 namespace dumpstate {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 // 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 */);
+}
+
+// Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
+Return<void> 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();
@@ -39,13 +46,23 @@
     return Void();
   }
 
+  if (mode < DumpstateMode::FULL || mode > DumpstateMode::DEFAULT) {
+    ALOGE("Invalid mode: %d\n", mode);
+    return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+  }
+
   DumpFileToFd(fd, "GCE INITIAL METADATA", "/initial.metadata");
 
   return Void();
 }
 
+Return<bool> DumpstateDevice::setDeviceLoggingEnabled(bool /* enable */) {
+  // Unsupported operation.
+  return false;
+}
+
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace dumpstate
 }  // namespace hardware
 }  // namespace android
diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.h b/guest/monitoring/dumpstate_ext/dumpstate_device.h
index 581a96b..2f6990d 100644
--- a/guest/monitoring/dumpstate_ext/dumpstate_device.h
+++ b/guest/monitoring/dumpstate_ext/dumpstate_device.h
@@ -15,19 +15,21 @@
  */
 #pragma once
 
-#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
+#include <android/hardware/dumpstate/1.1/IDumpstateDevice.h>
+#include <android/hardware/dumpstate/1.1/types.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
 namespace android {
 namespace hardware {
 namespace dumpstate {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
+using ::android::hardware::dumpstate::V1_1::DumpstateMode;
+using ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
@@ -37,10 +39,15 @@
 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;
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace dumpstate
 }  // namespace hardware
 }  // namespace android
diff --git a/guest/monitoring/dumpstate_ext/service.cpp b/guest/monitoring/dumpstate_ext/service.cpp
index 67eebe5..d8f339c 100644
--- a/guest/monitoring/dumpstate_ext/service.cpp
+++ b/guest/monitoring/dumpstate_ext/service.cpp
@@ -20,8 +20,8 @@
 
 using ::android::OK;
 using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
-using ::android::hardware::dumpstate::V1_0::implementation::DumpstateDevice;
+using ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
+using ::android::hardware::dumpstate::V1_1::implementation::DumpstateDevice;
 using ::android::hardware::joinRpcThreadpool;
 using ::android::sp;
 
diff --git a/host/commands/assemble_cvd/Android.bp b/host/commands/assemble_cvd/Android.bp
index 18b846f..807f18c 100644
--- a/host/commands/assemble_cvd/Android.bp
+++ b/host/commands/assemble_cvd/Android.bp
@@ -53,6 +53,7 @@
         "libz",
     ],
     static_libs: [
+        "libsparse",
         "libcuttlefish_host_config",
         "libcuttlefish_vm_manager",
         "libgflags",
@@ -62,7 +63,8 @@
     defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"],
 }
 
-sh_binary_host {
+python_binary_host {
     name: "cf_bpttool",
-    src: "cf_bpttool",
+    srcs: [ "cf_bpttool.py" ],
+    defaults: ["py2_only"],
 }
diff --git a/host/commands/assemble_cvd/cf_bpttool b/host/commands/assemble_cvd/cf_bpttool.py
similarity index 100%
rename from host/commands/assemble_cvd/cf_bpttool
rename to host/commands/assemble_cvd/cf_bpttool.py
diff --git a/host/commands/assemble_cvd/data_image.cc b/host/commands/assemble_cvd/data_image.cc
index c84cb33..1527d3c 100644
--- a/host/commands/assemble_cvd/data_image.cc
+++ b/host/commands/assemble_cvd/data_image.cc
@@ -15,9 +15,9 @@
 const int FSCK_ERROR_CORRECTED_REQUIRES_REBOOT = 2;
 
 bool ForceFsckImage(const char* data_image) {
-  int fsck_status = cvd::execute({"/sbin/e2fsck", "-y", "-f", data_image});
+  int fsck_status = cvd::execute({"/sbin/fsck.f2fs", "-y", "-f", data_image});
   if (fsck_status & ~(FSCK_ERROR_CORRECTED|FSCK_ERROR_CORRECTED_REQUIRES_REBOOT)) {
-    LOG(ERROR) << "`e2fsck -y -f " << data_image << "` failed with code "
+    LOG(ERROR) << "`fsck.f2fs -y -f " << data_image << "` failed with code "
                << fsck_status;
     return false;
   }
@@ -46,9 +46,9 @@
     if (!fsck_success) {
       return false;
     }
-    int resize_status = cvd::execute({"/sbin/resize2fs", data_image});
+    int resize_status = cvd::execute({"/sbin/resize.f2fs", data_image});
     if (resize_status != 0) {
-      LOG(ERROR) << "`resize2fs " << data_image << "` failed with code "
+      LOG(ERROR) << "`resize.f2fs " << data_image << "` failed with code "
                  << resize_status;
       return false;
     }
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index b30cedc..241912b 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -1,6 +1,10 @@
 #include "host/commands/assemble_cvd/flags.h"
 
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/statvfs.h>
+#include <unistd.h>
 
 #include <algorithm>
 #include <iostream>
@@ -37,7 +41,7 @@
             "'always_create'.");
 DEFINE_int32(blank_data_image_mb, 0,
              "The size of the blank data image to generate, MB.");
-DEFINE_string(blank_data_image_fmt, "ext4",
+DEFINE_string(blank_data_image_fmt, "f2fs",
               "The fs format for the blank data image. Used with mkfs.");
 DEFINE_string(qemu_gdb, "",
               "Debug flag to pass to qemu. e.g. -qemu_gdb=tcp::1234");
@@ -68,10 +72,6 @@
               "be vendor_boot.img in the directory specified by -system_image_dir.");
 DEFINE_int32(memory_mb, 2048,
              "Total amount of memory available for guest, MB.");
-DEFINE_string(mobile_interface, ForCurrentInstance("cvd-mbr-"),
-              "Network interface to use for mobile networking");
-DEFINE_string(mobile_tap_name, ForCurrentInstance("cvd-mtap-"),
-              "The name of the tap interface to use for mobile");
 DEFINE_string(serial_number, ForCurrentInstance("CUTTLEFISHCVD"),
               "Serial number to use for the device");
 DEFINE_string(assembly_dir,
@@ -93,13 +93,15 @@
 DEFINE_string(misc_image, "",
               "Location of the misc partition image. If the image does not "
               "exist, a blank new misc partition image is created.");
-DEFINE_string(composite_disk, "", "Location of the composite disk image. "
-                                  "If empty, a composite disk is not used.");
+DEFINE_string(composite_disk, "", "Location of the composite disk image. ");
 
 DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
             " host kernel. This is only used during transition of our clients."
             " Will be deprecated soon.");
-DEFINE_bool(start_vnc_server, false, "Whether to start the vnc server process.");
+DEFINE_bool(start_vnc_server, false, "Whether to start the vnc server process. "
+                                     "The VNC server runs at port 6443 + i for "
+                                     "the vsoc-i user or CUTTLEFISH_INSTANCE=i, "
+                                     "starting from 1.");
 
 DEFINE_bool(start_webrtc, false, "Whether to start the webrtc process.");
 
@@ -123,8 +125,6 @@
         false,
         "If enabled, exposes local adb service through a websocket.");
 
-DEFINE_int32(vnc_server_port, ForCurrentInstance(6444),
-             "The port on which the vnc server should listen");
 DEFINE_string(adb_mode, "vsock_half_tunnel",
               "Mode for ADB connection."
               "'vsock_tunnel' for a TCP connection tunneled through vsock, "
@@ -135,11 +135,6 @@
 DEFINE_bool(run_adb_connector, true,
             "Maintain adb connection by sending 'adb connect' commands to the "
             "server. Only relevant with -adb_mode=tunnel or vsock_tunnel");
-DEFINE_string(wifi_tap_name, ForCurrentInstance("cvd-wtap-"),
-              "The name of the tap interface to use for wifi");
-DEFINE_int32(vsock_guest_cid,
-             vsoc::GetDefaultPerInstanceVsockCid(),
-             "Guest identifier for vsock. Disabled if under 3.");
 
 DEFINE_string(uuid, vsoc::ForCurrentInstance(vsoc::kDefaultUuidPrefix),
               "UUID to use for the device. Random if not specified");
@@ -169,6 +164,12 @@
              "the slot will be chosen based on the misc partition if using a "
              "bootloader. It will default to 'a' if empty and not using a "
              "bootloader.");
+DEFINE_int32(num_instances, 1, "Number of Android guests to launch");
+DEFINE_bool(resume, true, "Resume using the disk from the last session, if "
+                          "possible. i.e., if --noresume is passed, the disk "
+                          "will be reset to the state it was initially launched "
+                          "in. This flag is ignored if the underlying partition "
+                          "images have been updated since the first launch.");
 
 namespace {
 
@@ -222,19 +223,20 @@
   return config.ForDefaultInstance().PerInstancePath("cuttlefish_config.json");
 }
 
-int GetHostPort() {
-  constexpr int kFirstHostPort = 6520;
-  return vsoc::ForCurrentInstance(kFirstHostPort);
-}
-
 int NumStreamers() {
   auto start_flags = {FLAGS_start_vnc_server, FLAGS_start_webrtc};
   return std::count(start_flags.begin(), start_flags.end(), true);
 }
 
+std::string StrForInstance(const std::string& prefix, int num) {
+  std::ostringstream stream;
+  stream << prefix << std::setfill('0') << std::setw(2) << num;
+  return stream.str();
+}
+
 // Initializes the config object and saves it to file. It doesn't return it, all
 // further uses of the config should happen through the singleton
-bool InitializeCuttlefishConfiguration(
+vsoc::CuttlefishConfig InitializeCuttlefishConfiguration(
     const cvd::BootImageUnpacker& boot_image_unpacker,
     const cvd::FetcherConfig& fetcher_config) {
   // At most one streamer can be started.
@@ -242,28 +244,20 @@
 
   vsoc::CuttlefishConfig tmp_config_obj;
   tmp_config_obj.set_assembly_dir(FLAGS_assembly_dir);
-  auto instance = tmp_config_obj.ForDefaultInstance();
-  // Set this first so that calls to PerInstancePath below are correct
-  instance.set_instance_dir(FLAGS_instance_dir);
   if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) {
-    LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
-    return false;
+    LOG(FATAL) << "Invalid vm_manager: " << FLAGS_vm_manager;
   }
   if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) {
-    LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
-    return false;
+    LOG(FATAL) << "Invalid vm_manager: " << FLAGS_vm_manager;
   }
   tmp_config_obj.set_vm_manager(FLAGS_vm_manager);
   tmp_config_obj.set_gpu_mode(FLAGS_gpu_mode);
   if (vm_manager::VmManager::ConfigureGpuMode(tmp_config_obj.vm_manager(),
                                               tmp_config_obj.gpu_mode()).empty()) {
-    LOG(ERROR) << "Invalid gpu_mode=" << FLAGS_gpu_mode <<
+    LOG(FATAL) << "Invalid gpu_mode=" << FLAGS_gpu_mode <<
                " does not work with vm_manager=" << FLAGS_vm_manager;
-    return false;
   }
 
-  instance.set_serial_number(FLAGS_serial_number);
-
   tmp_config_obj.set_cpus(FLAGS_cpus);
   tmp_config_obj.set_memory_mb(FLAGS_memory_mb);
 
@@ -275,10 +269,6 @@
   tmp_config_obj.set_gdb_flag(FLAGS_qemu_gdb);
   std::vector<std::string> adb = android::base::Split(FLAGS_adb_mode, ",");
   tmp_config_obj.set_adb_mode(std::set<std::string>(adb.begin(), adb.end()));
-  instance.set_host_port(GetHostPort());
-  instance.set_adb_ip_and_port("127.0.0.1:" + std::to_string(GetHostPort()));
-
-  instance.set_device_title(FLAGS_device_title);
   std::string discovered_kernel = fetcher_config.FindCvdFileWithSuffix(kKernelDefaultPath);
   std::string foreign_kernel = FLAGS_kernel_path.size() ? FLAGS_kernel_path : discovered_kernel;
   if (foreign_kernel.size()) {
@@ -298,8 +288,7 @@
   auto ramdisk_path = tmp_config_obj.AssemblyPath("ramdisk.img");
   auto vendor_ramdisk_path = tmp_config_obj.AssemblyPath("vendor_ramdisk.img");
   if (!boot_image_unpacker.HasRamdiskImage()) {
-    LOG(INFO) << "A ramdisk is required, but the boot image did not have one.";
-    return false;
+    LOG(FATAL) << "A ramdisk is required, but the boot image did not have one.";
   }
 
   tmp_config_obj.set_boot_image_kernel_cmdline(boot_image_unpacker.kernel_cmdline());
@@ -309,8 +298,6 @@
   tmp_config_obj.set_guest_force_normal_boot(FLAGS_guest_force_normal_boot);
   tmp_config_obj.set_extra_kernel_cmdline(FLAGS_extra_kernel_cmdline);
 
-  tmp_config_obj.set_virtual_disk_paths({FLAGS_composite_disk});
-
   tmp_config_obj.set_ramdisk_image_path(ramdisk_path);
   tmp_config_obj.set_vendor_ramdisk_image_path(vendor_ramdisk_path);
 
@@ -336,15 +323,6 @@
   tmp_config_obj.set_config_server_binary(
       vsoc::DefaultHostArtifactsPath("bin/config_server"));
 
-  instance.set_mobile_bridge_name(FLAGS_mobile_interface);
-  instance.set_mobile_tap_name(FLAGS_mobile_tap_name);
-
-  instance.set_wifi_tap_name(FLAGS_wifi_tap_name);
-
-  instance.set_vsock_guest_cid(FLAGS_vsock_guest_cid);
-
-  instance.set_uuid(FLAGS_uuid);
-
   tmp_config_obj.set_qemu_binary(FLAGS_qemu_binary);
   tmp_config_obj.set_crosvm_binary(FLAGS_crosvm_binary);
   tmp_config_obj.set_console_forwarder_binary(
@@ -355,7 +333,6 @@
   tmp_config_obj.set_enable_vnc_server(FLAGS_start_vnc_server);
   tmp_config_obj.set_vnc_server_binary(
       vsoc::DefaultHostArtifactsPath("bin/vnc_server"));
-  instance.set_vnc_server_port(FLAGS_vnc_server_port);
 
   tmp_config_obj.set_enable_webrtc(FLAGS_start_webrtc);
   tmp_config_obj.set_webrtc_binary(
@@ -394,6 +371,41 @@
 
   tmp_config_obj.set_cuttlefish_env_path(GetCuttlefishEnvPath());
 
+  std::vector<int> instance_nums;
+  for (int i = 0; i < FLAGS_num_instances; i++) {
+    instance_nums.push_back(vsoc::GetInstance() + i);
+  }
+
+  for (const auto& num : instance_nums) {
+    auto instance = tmp_config_obj.ForInstance(num);
+    auto const_instance = const_cast<const vsoc::CuttlefishConfig&>(tmp_config_obj)
+        .ForInstance(num);
+    // Set this first so that calls to PerInstancePath below are correct
+    instance.set_instance_dir(FLAGS_instance_dir + "." + std::to_string(num));
+    instance.set_serial_number(FLAGS_serial_number + std::to_string(num));
+
+    instance.set_mobile_bridge_name(StrForInstance("cvd-mbr-", num));
+    instance.set_mobile_tap_name(StrForInstance("cvd-mtap-", num));
+
+    instance.set_wifi_tap_name(StrForInstance("cvd-wtap-", num));
+
+    instance.set_vsock_guest_cid(3 + num - 1);
+
+    instance.set_uuid(FLAGS_uuid);
+
+    instance.set_vnc_server_port(6444 + num - 1);
+    instance.set_host_port(6520 + num - 1);
+    instance.set_adb_ip_and_port("127.0.0.1:" + std::to_string(6520 + num - 1));
+
+    instance.set_device_title(FLAGS_device_title);
+
+    instance.set_virtual_disk_paths({const_instance.PerInstancePath("overlay.img")});
+  }
+
+  return tmp_config_obj;
+}
+
+bool SaveConfig(const vsoc::CuttlefishConfig& tmp_config_obj) {
   auto config_file = GetConfigFilePath(tmp_config_obj);
   auto config_link = vsoc::GetGlobalConfigFileLink();
   // Save the config object before starting any host process
@@ -456,32 +468,110 @@
   return ResolveInstanceFiles();
 }
 
-bool CleanPriorFiles() {
-  // Everything on the instance directory
-  std::string prior_files = FLAGS_instance_dir + "/*";
-  // Everything in the assembly directory
-  prior_files += " " + FLAGS_assembly_dir + "/*";
-  // The environment file
-  prior_files += " " + GetCuttlefishEnvPath();
-  // The global link to the config file
-  prior_files += " " + vsoc::GetGlobalConfigFileLink();
+std::string cpp_basename(const std::string& str) {
+  char* copy = strdup(str.c_str()); // basename may modify its argument
+  std::string ret(basename(copy));
+  free(copy);
+  return ret;
+}
+
+bool CleanPriorFiles(const std::string& path, const std::set<std::string>& preserving) {
+  if (preserving.count(cpp_basename(path))) {
+    LOG(INFO) << "Preserving: " << path;
+    return true;
+  }
+  struct stat statbuf;
+  if (lstat(path.c_str(), &statbuf) < 0) {
+    int error_num = errno;
+    if (error_num == ENOENT) {
+      return true;
+    } else {
+      LOG(ERROR) << "Could not stat \"" << path << "\": " << strerror(error_num);
+      return false;
+    }
+  }
+  if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
+    LOG(INFO) << "Deleting: " << path;
+    if (unlink(path.c_str()) < 0) {
+      int error_num = errno;
+      LOG(ERROR) << "Could not unlink \"" << path << "\", error was " << strerror(error_num);
+      return false;
+    }
+    return true;
+  }
+  std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(path.c_str()), closedir);
+  if (!dir) {
+    int error_num = errno;
+    LOG(ERROR) << "Could not clean \"" << path << "\": error was " << strerror(error_num);
+    return false;
+  }
+  for (auto entity = readdir(dir.get()); entity != nullptr; entity = readdir(dir.get())) {
+    std::string entity_name(entity->d_name);
+    if (entity_name == "." || entity_name == "..") {
+      continue;
+    }
+    std::string entity_path = path + "/" + entity_name;
+    if (!CleanPriorFiles(entity_path.c_str(), preserving)) {
+      return false;
+    }
+  }
+  if (rmdir(path.c_str()) < 0) {
+    if (!(errno == EEXIST || errno == ENOTEMPTY)) {
+      // If EEXIST or ENOTEMPTY, probably because a file was preserved
+      int error_num = errno;
+      LOG(ERROR) << "Could not rmdir \"" << path << "\", error was " << strerror(error_num);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool CleanPriorFiles(const std::vector<std::string>& paths, const std::set<std::string>& preserving) {
+  std::string prior_files;
+  for (auto path : paths) {
+    struct stat statbuf;
+    if (stat(path.c_str(), &statbuf) < 0 && errno != ENOENT) {
+      // If ENOENT, it doesn't exist yet, so there is no work to do'
+      int error_num = errno;
+      LOG(ERROR) << "Could not stat \"" << path << "\": " << strerror(error_num);
+      return false;
+    }
+    bool is_directory = (statbuf.st_mode & S_IFMT) == S_IFDIR;
+    prior_files += (is_directory ? (path + "/*") : path) + " ";
+  }
   LOG(INFO) << "Assuming prior files of " << prior_files;
-  std::string fuser_cmd = "fuser " + prior_files + " 2> /dev/null";
-  int rval = std::system(fuser_cmd.c_str());
-  // fuser returns 0 if any of the files are open
+  std::string lsof_cmd = "lsof -t " + prior_files + " >/dev/null 2>&1";
+  int rval = std::system(lsof_cmd.c_str());
+  // lsof returns 0 if any of the files are open
   if (WEXITSTATUS(rval) == 0) {
     LOG(ERROR) << "Clean aborted: files are in use";
     return false;
   }
-  std::string clean_command = "rm -rf " + prior_files;
-  rval = std::system(clean_command.c_str());
-  if (WEXITSTATUS(rval) != 0) {
-    LOG(ERROR) << "Remove of files failed";
-    return false;
+  for (const auto& path : paths) {
+    if (!CleanPriorFiles(path, preserving)) {
+      LOG(ERROR) << "Remove of file under \"" << path << "\" failed";
+      return false;
+    }
   }
   return true;
 }
 
+bool CleanPriorFiles(const vsoc::CuttlefishConfig& config, const std::set<std::string>& preserving) {
+  std::vector<std::string> paths = {
+    // Everything in the assembly directory
+    FLAGS_assembly_dir,
+    // The environment file
+    GetCuttlefishEnvPath(),
+    // The global link to the config file
+    vsoc::GetGlobalConfigFileLink(),
+  };
+  for (const auto& instance : config.Instances()) {
+    paths.push_back(instance.instance_dir());
+  }
+  paths.push_back(FLAGS_instance_dir);
+  return CleanPriorFiles(paths, preserving);
+}
+
 bool DecompressKernel(const std::string& src, const std::string& dst) {
   cvd::Command decomp_cmd(vsoc::DefaultHostArtifactsPath("bin/extract-vmlinux"));
   decomp_cmd.AddParameter(src);
@@ -537,23 +627,20 @@
   return partitions;
 }
 
-bool ShouldCreateCompositeDisk() {
-  if (FLAGS_vm_manager == vm_manager::CrosvmManager::name()) {
-    // The crosvm implementation is very fast to rebuild but also more brittle due to being split
-    // into multiple files. The QEMU implementation is slow to build, but completely self-contained
-    // at that point. Therefore, always rebuild on crosvm but check if it is necessary for QEMU.
-    return true;
-  }
-  auto composite_age = cvd::FileModificationTime(FLAGS_composite_disk);
+std::chrono::system_clock::time_point LastUpdatedInputDisk() {
+  std::chrono::system_clock::time_point ret;
   for (auto& partition : disk_config()) {
-    auto partition_age = cvd::FileModificationTime(partition.image_file_path);
-    if (partition_age >= composite_age) {
-      LOG(INFO) << "composite disk age was \"" << std::chrono::system_clock::to_time_t(composite_age) << "\", "
-                << "partition age was \"" << std::chrono::system_clock::to_time_t(partition_age) << "\"";
-      return true;
+    auto partition_mod_time = cvd::FileModificationTime(partition.image_file_path);
+    if (partition_mod_time > ret) {
+      ret = partition_mod_time;
     }
   }
-  return false;
+  return ret;
+}
+
+bool ShouldCreateCompositeDisk() {
+  auto composite_age = cvd::FileModificationTime(FLAGS_composite_disk);
+  return composite_age < LastUpdatedInputDisk();
 }
 
 bool ConcatRamdisks(const std::string& new_ramdisk_path, const std::string& ramdisk_a_path,
@@ -606,7 +693,7 @@
     }
     std::string header_path = config.AssemblyPath("gpt_header.img");
     std::string footer_path = config.AssemblyPath("gpt_footer.img");
-    create_composite_disk(disk_config(), header_path, footer_path, FLAGS_composite_disk);
+    CreateCompositeDisk(disk_config(), header_path, footer_path, FLAGS_composite_disk);
   } else {
     auto existing_size = cvd::FileSize(FLAGS_composite_disk);
     auto available_space = AvailableSpaceAtPath(FLAGS_composite_disk);
@@ -616,7 +703,7 @@
       LOG(ERROR) << "Got " << available_space;
       return false;
     }
-    aggregate_image(disk_config(), FLAGS_composite_disk);
+    AggregateImage(disk_config(), FLAGS_composite_disk);
   }
   return true;
 }
@@ -630,39 +717,72 @@
     exit(AssemblerExitCodes::kArgumentParsingError);
   }
 
-  // Clean up prior files before saving the config file (doing it after would
-  // delete it)
-  if (!CleanPriorFiles()) {
-    LOG(ERROR) << "Failed to clean prior files";
-    exit(AssemblerExitCodes::kPrioFilesCleanupError);
-  }
-  // Create assembly directory if it doesn't exist.
-  if (!cvd::DirectoryExists(FLAGS_assembly_dir.c_str())) {
-    LOG(INFO) << "Setting up " << FLAGS_assembly_dir;
-    if (mkdir(FLAGS_assembly_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
-      LOG(ERROR) << "Failed to create assembly directory: "
-                 << FLAGS_assembly_dir << ". Error: " << errno;
-      exit(AssemblerExitCodes::kAssemblyDirCreationError);
+  auto boot_img_unpacker =
+    cvd::BootImageUnpacker::FromImages(FLAGS_boot_image,
+                                      FLAGS_vendor_boot_image);
+  {
+    // The config object is created here, but only exists in memory until the
+    // SaveConfig line below. Don't launch cuttlefish subprocesses between these
+    // two operations, as those will assume they can read the config object from
+    // disk.
+    auto config = InitializeCuttlefishConfiguration(*boot_img_unpacker, fetcher_config);
+    std::set<std::string> preserving;
+    if (FLAGS_resume && ShouldCreateCompositeDisk()) {
+      LOG(WARNING) << "Requested resuming a previous session (the default behavior) "
+                   << "but the base images have changed under the overlay, making the "
+                   << "overlay incompatible. Wiping the overlay files.";
+    } else if (FLAGS_resume && !ShouldCreateCompositeDisk()) {
+      preserving.insert("overlay.img");
+      preserving.insert("gpt_header.img");
+      preserving.insert("gpt_footer.img");
+      preserving.insert("composite.img");
+      preserving.insert("access-kregistry");
     }
-  }
-  // Create instance directory if it doesn't exist.
-  if (!cvd::DirectoryExists(FLAGS_instance_dir.c_str())) {
-    LOG(INFO) << "Setting up " << FLAGS_instance_dir;
-    if (mkdir(FLAGS_instance_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
-      LOG(ERROR) << "Failed to create instance directory: "
-                 << FLAGS_instance_dir << ". Error: " << errno;
-      exit(AssemblerExitCodes::kInstanceDirCreationError);
+    if (!CleanPriorFiles(config, preserving)) {
+      LOG(ERROR) << "Failed to clean prior files";
+      exit(AssemblerExitCodes::kPrioFilesCleanupError);
+    }
+    // Create assembly directory if it doesn't exist.
+    if (!cvd::DirectoryExists(FLAGS_assembly_dir.c_str())) {
+      LOG(INFO) << "Setting up " << FLAGS_assembly_dir;
+      if (mkdir(FLAGS_assembly_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0
+          && errno != EEXIST) {
+        LOG(ERROR) << "Failed to create assembly directory: "
+                  << FLAGS_assembly_dir << ". Error: " << errno;
+        exit(AssemblerExitCodes::kAssemblyDirCreationError);
+      }
+    }
+    for (const auto& instance : config.Instances()) {
+      // Create instance directory if it doesn't exist.
+      if (!cvd::DirectoryExists(instance.instance_dir().c_str())) {
+        LOG(INFO) << "Setting up " << FLAGS_instance_dir << ".N";
+        if (mkdir(instance.instance_dir().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0
+            && errno != EEXIST) {
+          LOG(ERROR) << "Failed to create instance directory: "
+                    << FLAGS_instance_dir << ". Error: " << errno;
+          exit(AssemblerExitCodes::kInstanceDirCreationError);
+        }
+      }
+      auto internal_dir = instance.instance_dir() + "/" + vsoc::kInternalDirName;
+      if (!cvd::DirectoryExists(internal_dir)) {
+        if (mkdir(internal_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0
+           && errno != EEXIST) {
+          LOG(ERROR) << "Failed to create internal instance directory: "
+                    << internal_dir << ". Error: " << errno;
+          exit(AssemblerExitCodes::kInstanceDirCreationError);
+        }
+      }
+    }
+    if (!SaveConfig(config)) {
+      LOG(ERROR) << "Failed to initialize configuration";
+      exit(AssemblerExitCodes::kCuttlefishConfigurationInitError);
     }
   }
 
-  auto internal_dir = FLAGS_instance_dir + "/" + vsoc::kInternalDirName;
-  if (!cvd::DirectoryExists(internal_dir)) {
-    if (mkdir(internal_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) <
-        0) {
-      LOG(ERROR) << "Failed to create internal instance directory: "
-                 << internal_dir << ". Error: " << errno;
-      exit(AssemblerExitCodes::kInstanceDirCreationError);
-    }
+  std::string first_instance = FLAGS_instance_dir + "." + std::to_string(vsoc::GetInstance());
+  if (symlink(first_instance.c_str(), FLAGS_instance_dir.c_str()) < 0) {
+    LOG(ERROR) << "Could not symlink \"" << first_instance << "\" to \"" << FLAGS_instance_dir << "\"";
+    exit(cvd::kCuttlefishConfigurationInitError);
   }
 
   if (!cvd::FileHasContent(FLAGS_boot_image)) {
@@ -675,14 +795,6 @@
     exit(cvd::kCuttlefishConfigurationInitError);
   }
 
-  auto boot_img_unpacker =
-    cvd::BootImageUnpacker::FromImages(FLAGS_boot_image,
-                                       FLAGS_vendor_boot_image);
-
-  if (!InitializeCuttlefishConfiguration(*boot_img_unpacker, fetcher_config)) {
-    LOG(ERROR) << "Failed to initialize configuration";
-    exit(AssemblerExitCodes::kCuttlefishConfigurationInitError);
-  }
   // Do this early so that the config object is ready for anything that needs it
   auto config = vsoc::CuttlefishConfig::Get();
   if (!config) {
@@ -751,9 +863,10 @@
     CreateBlankImage(FLAGS_metadata_image, FLAGS_blank_metadata_image_mb, "none");
   }
 
-  if (!cvd::FileExists(config->ForDefaultInstance().access_kregistry_path())) {
-    CreateBlankImage(config->ForDefaultInstance().access_kregistry_path(), 1,
-                     "none", "64K");
+  for (const auto& instance : config->Instances()) {
+    if (!cvd::FileExists(instance.access_kregistry_path())) {
+      CreateBlankImage(instance.access_kregistry_path(), 1, "none", "64K");
+    }
   }
 
   if (SuperImageNeedsRebuilding(fetcher_config, *config)) {
@@ -769,11 +882,26 @@
     }
   }
 
-  // Check that the files exist
-  for (const auto& file : config->virtual_disk_paths()) {
-    if (!file.empty() && !cvd::FileHasContent(file.c_str())) {
-      LOG(ERROR) << "File not found: " << file;
-      exit(cvd::kCuttlefishConfigurationInitError);
+  for (auto instance : config->Instances()) {
+    auto overlay_path = instance.PerInstancePath("overlay.img");
+    if (!cvd::FileExists(overlay_path) || ShouldCreateCompositeDisk() || !FLAGS_resume
+        || cvd::FileModificationTime(overlay_path) < cvd::FileModificationTime(FLAGS_composite_disk)) {
+      if (FLAGS_resume) {
+        LOG(WARNING) << "Requested to continue an existing session, but the overlay was "
+                     << "newer than its underlying composite disk. Wiping the overlay.";
+      }
+      CreateQcowOverlay(config->crosvm_binary(), FLAGS_composite_disk, overlay_path);
+      CreateBlankImage(instance.access_kregistry_path(), 1, "none", "64K");
+    }
+  }
+
+  for (auto instance : config->Instances()) {
+    // Check that the files exist
+    for (const auto& file : instance.virtual_disk_paths()) {
+      if (!file.empty() && !cvd::FileHasContent(file.c_str())) {
+        LOG(ERROR) << "File not found: " << file;
+        exit(cvd::kCuttlefishConfigurationInitError);
+      }
     }
   }
 
diff --git a/host/commands/assemble_cvd/image_aggregator.cc b/host/commands/assemble_cvd/image_aggregator.cc
index 17fe9db..eac6a2e 100644
--- a/host/commands/assemble_cvd/image_aggregator.cc
+++ b/host/commands/assemble_cvd/image_aggregator.cc
@@ -16,6 +16,11 @@
 
 #include "host/commands/assemble_cvd/image_aggregator.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+
 #include <fstream>
 #include <string>
 #include <vector>
@@ -23,6 +28,7 @@
 #include <glog/logging.h>
 #include <json/json.h>
 #include <google/protobuf/text_format.h>
+#include <sparse/sparse.h>
 
 #include "common/libs/fs/shared_buf.h"
 #include "common/libs/fs/shared_fd.h"
@@ -38,15 +44,36 @@
 
 const std::string BPTTOOL_FILE_PATH = "bin/cf_bpttool";
 
-Json::Value bpttool_input(const std::vector<ImagePartition>& partitions) {
+Json::Value BpttoolInput(const std::vector<ImagePartition>& partitions) {
   std::vector<off_t> file_sizes;
   off_t total_size = 20 << 20; // 20 MB for padding
   for (auto& partition : partitions) {
-    off_t partition_file_size = cvd::FileSize(partition.image_file_path);
-    if (partition_file_size == 0) {
-      LOG(FATAL) << "Expected partition file \"" << partition.image_file_path
-                 << "\" but it was missing";
+    LOG(INFO) << "Examining " << partition.label;
+    auto file = cvd::SharedFD::Open(partition.image_file_path.c_str(), O_RDONLY);
+    if (!file->IsOpen()) {
+      LOG(FATAL) << "Could not open \"" << partition.image_file_path
+                 << "\": " << file->StrError();
+      break;
     }
+    int fd = file->UNMANAGED_Dup();
+    auto sparse = sparse_file_import(fd, /* verbose */ false, /* crc */ false);
+    off_t partition_file_size = 0;
+    if (sparse) {
+      partition_file_size = sparse_file_len(sparse, /* sparse */ false,
+                                            /* crc */ true);
+      sparse_file_destroy(sparse);
+      close(fd);
+      LOG(INFO) << "was sparse";
+    } else {
+      partition_file_size = cvd::FileSize(partition.image_file_path);
+      if (partition_file_size == 0) {
+        LOG(FATAL) << "Could not get file size of \"" << partition.image_file_path
+                  << "\"";
+        break;
+      }
+      LOG(INFO) << "was not sparse";
+    }
+    LOG(INFO) << "size was " << partition_file_size;
     total_size += partition_file_size;
     file_sizes.push_back(partition_file_size);
   }
@@ -65,7 +92,7 @@
   return bpttool_input_json;
 }
 
-std::string create_file(size_t len) {
+std::string CreateFile(size_t len) {
   char file_template[] = "/tmp/diskXXXXXX";
   int fd = mkstemp(file_template);
   if (fd < 0) {
@@ -97,7 +124,7 @@
   for (auto& bpt_partition: bpt_file["partitions"]) {
     if (bpt_partition["offset"].asUInt64() != previous_end) {
       ComponentDisk* component = disk.add_component_disks();
-      component->set_file_path(create_file(bpt_partition["offset"].asUInt64() - previous_end));
+      component->set_file_path(CreateFile(bpt_partition["offset"].asUInt64() - previous_end));
       component->set_offset(previous_end);
     }
     ComponentDisk* component = disk.add_component_disks();
@@ -113,7 +140,7 @@
   size_t footer_start = bpt_file["settings"]["disk_size"].asUInt64() - GPT_FOOTER_SIZE;
   if (footer_start != previous_end) {
     ComponentDisk* component = disk.add_component_disks();
-    component->set_file_path(create_file(footer_start - previous_end));
+    component->set_file_path(CreateFile(footer_start - previous_end));
     component->set_offset(previous_end);
   }
   ComponentDisk* footer = disk.add_component_disks();
@@ -123,7 +150,7 @@
   return disk;
 }
 
-cvd::SharedFD json_to_fd(const Json::Value& json) {
+cvd::SharedFD JsonToFd(const Json::Value& json) {
   Json::FastWriter json_writer;
   std::string json_string = json_writer.write(json);
   cvd::SharedFD pipe[2];
@@ -137,7 +164,7 @@
   return pipe[0];
 }
 
-Json::Value fd_to_json(cvd::SharedFD fd) {
+Json::Value FdToJson(cvd::SharedFD fd) {
   std::string contents;
   cvd::ReadAll(fd, &contents);
   Json::Reader reader;
@@ -148,7 +175,7 @@
   return json;
 }
 
-cvd::SharedFD bpttool_make_table(const cvd::SharedFD& input) {
+cvd::SharedFD BpttoolMakeTable(const cvd::SharedFD& input) {
   auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH);
   cvd::Command bpttool_cmd(bpttool_path);
   bpttool_cmd.AddParameter("make_table");
@@ -165,7 +192,7 @@
   return output_pipe[0];
 }
 
-cvd::SharedFD bpttool_make_partition_table(cvd::SharedFD input) {
+cvd::SharedFD BpttoolMakePartitionTable(cvd::SharedFD input) {
   auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH);
   cvd::Command bpttool_cmd(bpttool_path);
   bpttool_cmd.AddParameter("make_table");
@@ -203,8 +230,8 @@
   }
 }
 
-void bpttool_make_disk_image(const std::vector<ImagePartition>& partitions,
-                             cvd::SharedFD table, const std::string& output) {
+void BptToolMakeDiskImage(const std::vector<ImagePartition>& partitions,
+                          cvd::SharedFD table, const std::string& output) {
   auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH);
   cvd::Command bpttool_cmd(bpttool_path);
   bpttool_cmd.AddParameter("make_disk_image");
@@ -221,28 +248,77 @@
   }
 }
 
+void DeAndroidSparse(const std::vector<ImagePartition>& partitions) {
+  for (const auto& partition : partitions) {
+    auto file = cvd::SharedFD::Open(partition.image_file_path.c_str(), O_RDONLY);
+    if (!file->IsOpen()) {
+      LOG(FATAL) << "Could not open \"" << partition.image_file_path
+                  << "\": " << file->StrError();
+      break;
+    }
+    int fd = file->UNMANAGED_Dup();
+    auto sparse = sparse_file_import(fd, /* verbose */ false, /* crc */ false);
+    if (!sparse) {
+      close(fd);
+      continue;
+    }
+    LOG(INFO) << "Desparsing " << partition.image_file_path;
+    std::string out_file_name = partition.image_file_path + ".desparse";
+    auto out_file = cvd::SharedFD::Open(out_file_name.c_str(), O_RDWR | O_CREAT | O_TRUNC,
+                                        S_IRUSR | S_IWUSR | S_IRGRP);
+    int write_fd = out_file->UNMANAGED_Dup();
+    int write_status = sparse_file_write(sparse, write_fd, /* gz */ false,
+                                         /* sparse */ false, /* crc */ false);
+    if (write_status < 0) {
+      LOG(FATAL) << "Failed to desparse \"" << partition.image_file_path << "\": " << write_status;
+    }
+    close(write_fd);
+    if (rename(out_file_name.c_str(), partition.image_file_path.c_str()) < 0) {
+      int error_num = errno;
+      LOG(FATAL) << "Could not move \"" << out_file_name << "\" to \""
+                 << partition.image_file_path << "\": " << strerror(error_num);
+    }
+    sparse_file_destroy(sparse);
+    close(fd);
+  }
+}
+
 } // namespace
 
-void aggregate_image(const std::vector<ImagePartition>& partitions,
-                     const std::string& output_path) {
-  auto bpttool_input_json = bpttool_input(partitions);
-  auto input_json_fd = json_to_fd(bpttool_input_json);
-  auto table_fd = bpttool_make_table(input_json_fd);
-  bpttool_make_disk_image(partitions, table_fd, output_path);
+void AggregateImage(const std::vector<ImagePartition>& partitions,
+                    const std::string& output_path) {
+  DeAndroidSparse(partitions);
+  auto bpttool_input_json = BpttoolInput(partitions);
+  auto input_json_fd = JsonToFd(bpttool_input_json);
+  auto table_fd = BpttoolMakeTable(input_json_fd);
+  BptToolMakeDiskImage(partitions, table_fd, output_path);
 };
 
-void create_composite_disk(std::vector<ImagePartition> partitions,
-                           const std::string& header_file,
-                           const std::string& footer_file,
-                           const std::string& output_path) {
-  auto bpttool_input_json = bpttool_input(partitions);
-  auto table_fd = bpttool_make_table(json_to_fd(bpttool_input_json));
-  auto table = fd_to_json(table_fd);
-  auto partition_table_fd = bpttool_make_partition_table(json_to_fd(bpttool_input_json));
+void CreateCompositeDisk(std::vector<ImagePartition> partitions,
+                         const std::string& header_file,
+                         const std::string& footer_file,
+                         const std::string& output_composite_path) {
+  auto bpttool_input_json = BpttoolInput(partitions);
+  auto table_fd = BpttoolMakeTable(JsonToFd(bpttool_input_json));
+  auto table = FdToJson(table_fd);
+  auto partition_table_fd = BpttoolMakePartitionTable(JsonToFd(bpttool_input_json));
   CreateGptFiles(partition_table_fd, header_file, footer_file);
   auto composite_proto = MakeCompositeDiskSpec(table, partitions, header_file, footer_file);
-  std::ofstream output(output_path.c_str(), std::ios::binary | std::ios::trunc);
-  output << "composite_disk\x1d";
-  composite_proto.SerializeToOstream(&output);
-  output.flush();
+  std::ofstream composite(output_composite_path.c_str(), std::ios::binary | std::ios::trunc);
+  composite << "composite_disk\x1d";
+  composite_proto.SerializeToOstream(&composite);
+  composite.flush();
+}
+
+void CreateQcowOverlay(const std::string& crosvm_path,
+                       const std::string& backing_file,
+                       const std::string& output_overlay_path) {
+  cvd::Command crosvm_qcow2_cmd(crosvm_path);
+  crosvm_qcow2_cmd.AddParameter("create_qcow2");
+  crosvm_qcow2_cmd.AddParameter("--backing_file=", backing_file);
+  crosvm_qcow2_cmd.AddParameter(output_overlay_path);
+  int success = crosvm_qcow2_cmd.Start().Wait();
+  if (success != 0) {
+    LOG(FATAL) << "Unable to run crosvm create_qcow2. Exited with status " << success;
+  }
 }
diff --git a/host/commands/assemble_cvd/image_aggregator.h b/host/commands/assemble_cvd/image_aggregator.h
index a4394e8..d27931b 100644
--- a/host/commands/assemble_cvd/image_aggregator.h
+++ b/host/commands/assemble_cvd/image_aggregator.h
@@ -24,9 +24,12 @@
   std::string image_file_path;
 };
 
-void aggregate_image(const std::vector<ImagePartition>& partitions,
-                     const std::string& output_path);
-void create_composite_disk(std::vector<ImagePartition> partitions,
-                           const std::string& header_file,
-                           const std::string& footer_file,
-                           const std::string& output_path);
+void AggregateImage(const std::vector<ImagePartition>& partitions,
+                    const std::string& output_path);
+void CreateCompositeDisk(std::vector<ImagePartition> partitions,
+                         const std::string& header_file,
+                         const std::string& footer_file,
+                         const std::string& output_composite_path);
+void CreateQcowOverlay(const std::string& crosvm_path,
+                       const std::string& backing_file,
+                       const std::string& output_overlay_path);
diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc
index fcc0dc1..78d2750 100644
--- a/host/commands/assemble_cvd/super_image_mixer.cc
+++ b/host/commands/assemble_cvd/super_image_mixer.cc
@@ -46,9 +46,8 @@
     }
     std::string expected_filename = "target_files-" + file_iter.second.build_id;
     if (file_path.find(expected_filename) != std::string::npos) {
-      continue;
+      return file_path;
     }
-    return file_path;;
   }
   return "";
 }
diff --git a/host/commands/launch/launch_cvd.cc b/host/commands/launch/launch_cvd.cc
index 9d3b108..6cc7c93 100644
--- a/host/commands/launch/launch_cvd.cc
+++ b/host/commands/launch/launch_cvd.cc
@@ -39,6 +39,7 @@
  */
 DEFINE_bool(run_file_discovery, true,
             "Whether to run file discovery or get input files from stdin.");
+DEFINE_int32(num_instances, 1, "Number of Android guests to launch");
 
 namespace {
 
@@ -95,8 +96,8 @@
 
   gflags::HandleCommandLineHelpFlags();
 
-  cvd::SharedFD assembler_stdout, runner_stdin;
-  cvd::SharedFD::Pipe(&runner_stdin, &assembler_stdout);
+  cvd::SharedFD assembler_stdout, assembler_stdout_capture;
+  cvd::SharedFD::Pipe(&assembler_stdout_capture, &assembler_stdout);
 
   cvd::SharedFD launcher_report, assembler_stdin;
   bool should_generate_report = FLAGS_run_file_discovery;
@@ -109,13 +110,18 @@
   auto assemble_proc = StartAssembler(std::move(assembler_stdin),
                                       std::move(assembler_stdout),
                                       forwarder.ArgvForSubprocess(kAssemblerBin));
-  auto run_proc = StartRunner(std::move(runner_stdin),
-                              forwarder.ArgvForSubprocess(kRunnerBin));
 
   if (should_generate_report) {
     WriteFiles(AvailableFilesReport(), std::move(launcher_report));
   }
 
+  std::string assembler_output;
+  if (cvd::ReadAll(assembler_stdout_capture, &assembler_output) < 0) {
+    int error_num = errno;
+    LOG(ERROR) << "Read error getting output from assemble_cvd: " << strerror(error_num);
+    return -1;
+  }
+
   auto assemble_ret = assemble_proc.Wait();
   if (assemble_ret != 0) {
     LOG(ERROR) << "assemble_cvd returned " << assemble_ret;
@@ -124,11 +130,32 @@
     LOG(INFO) << "assemble_cvd exited successfully.";
   }
 
-  auto run_ret = run_proc.Wait();
-  if (run_ret != 0) {
-    LOG(ERROR) << "run_cvd returned " << run_ret;
-  } else {
-    LOG(INFO) << "run_cvd exited successfully.";
+  std::vector<cvd::Subprocess> runners;
+  for (int i = 0; i < FLAGS_num_instances; i++) {
+    cvd::SharedFD runner_stdin_in, runner_stdin_out;
+    cvd::SharedFD::Pipe(&runner_stdin_out, &runner_stdin_in);
+    std::string instance_name = std::to_string(i + vsoc::GetInstance());
+    setenv("CUTTLEFISH_INSTANCE", instance_name.c_str(), /* overwrite */ 1);
+
+    auto run_proc = StartRunner(std::move(runner_stdin_out),
+                                forwarder.ArgvForSubprocess(kRunnerBin));
+    runners.push_back(std::move(run_proc));
+    if (cvd::WriteAll(runner_stdin_in, assembler_output) < 0) {
+      int error_num = errno;
+      LOG(ERROR) << "Could not write to run_cvd: " << strerror(error_num);
+      return -1;
+    }
   }
-  return run_ret;
+
+  bool run_cvd_failure = false;
+  for (auto& run_proc : runners) {
+    auto run_ret = run_proc.Wait();
+    if (run_ret != 0) {
+      run_cvd_failure = true;
+      LOG(ERROR) << "run_cvd returned " << run_ret;
+    } else {
+      LOG(INFO) << "run_cvd exited successfully.";
+    }
+  }
+  return run_cvd_failure ? -1 : 0;
 }
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index 3c92959..dc2e108 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -110,7 +110,8 @@
   cmd->AddParameter("-keyboard_fd=", keyboard_server);
 
   cvd::SharedFD frames_server;
-  if (config.gpu_mode() == vsoc::kGpuModeDrmVirgl) {
+  if (config.gpu_mode() == vsoc::kGpuModeDrmVirgl ||
+      config.gpu_mode() == vsoc::kGpuModeGfxStream) {
     frames_server = CreateUnixInputServer(instance.frames_socket_path());
   } else {
     frames_server = cvd::SharedFD::VsockServer(SOCK_STREAM);
diff --git a/host/commands/stop_cvd/main.cc b/host/commands/stop_cvd/main.cc
index a598f3d..65dbeb7 100644
--- a/host/commands/stop_cvd/main.cc
+++ b/host/commands/stop_cvd/main.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <dirent.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <stdio.h>
@@ -35,6 +36,7 @@
 #include <string>
 #include <vector>
 
+#include <android-base/strings.h>
 #include <gflags/gflags.h>
 #include <glog/logging.h>
 
@@ -50,23 +52,57 @@
              "command. A value of zero means wait indefinetly");
 
 namespace {
+
+std::set<std::string> FallbackPaths() {
+  std::set<std::string> paths;
+  std::string parent_path = cvd::StringFromEnv("HOME", ".");
+  paths.insert(parent_path + "/cuttlefish_assembly");
+  paths.insert(parent_path + "/cuttlefish_assembly/*");
+
+  std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(parent_path.c_str()), closedir);
+  for (auto entity = readdir(dir.get()); entity != nullptr; entity = readdir(dir.get())) {
+    std::string subdir(entity->d_name);
+    if (!android::base::StartsWith(subdir, "cuttlefish_runtime.")) {
+      continue;
+    }
+    auto instance_dir = parent_path + "/" + subdir;
+    // Add the instance directory
+    paths.insert(instance_dir);
+    // Add files in instance dir
+    paths.insert(instance_dir + "/*");
+    // Add files in the tombstone directory
+    paths.insert(instance_dir + "/tombstones/*");
+    // Add files in the internal directory
+    paths.insert(instance_dir + "/" + std::string(vsoc::kInternalDirName) + "/*");
+  }
+  return paths;
+}
+
+std::set<std::string> PathsForInstance(const vsoc::CuttlefishConfig& config,
+                                       const vsoc::CuttlefishConfig::InstanceSpecific instance) {
+  return {
+    config.assembly_dir(),
+    config.assembly_dir() + "/*",
+    instance.instance_dir(),
+    instance.PerInstancePath("*"),
+    instance.PerInstancePath("tombstones"),
+    instance.PerInstancePath("tombstones/*"),
+    instance.instance_internal_dir(),
+    instance.PerInstanceInternalPath("*"),
+  };
+}
+
 // Gets a set of the possible process groups of a previous launch
-std::set<pid_t> GetCandidateProcessGroups() {
-  std::string cmd = "fuser";
-  // Add the instance directory
-  auto instance_dir = cvd::StringFromEnv("HOME", ".") + "/cuttlefish_runtime";
-  cmd += " " + instance_dir;
-  // Add files in instance dir
-  cmd += " " + instance_dir + "/*";
-  // Add files in the tombstone directory
-  cmd += " " + instance_dir + "/tombstones/*";
-  // Add files in the internal directory
-  cmd += ((" " + instance_dir + "/") + vsoc::kInternalDirName) + "/*";
-  // Add the shared memory file
-  cmd += " " + vsoc::ForCurrentInstance("/dev/shm/cvd-");
-  std::shared_ptr<FILE> cmd_out(popen(cmd.c_str(), "r"), pclose);
+std::set<pid_t> GetCandidateProcessGroups(const std::set<std::string>& paths) {
+  std::stringstream cmd;
+  cmd << "lsof -t 2>/dev/null";
+  for (const auto& path : paths) {
+    cmd << " " << path;
+  }
+  std::string cmd_str = cmd.str();
+  std::shared_ptr<FILE> cmd_out(popen(cmd_str.c_str(), "r"), pclose);
   if (!cmd_out) {
-    LOG(ERROR) << "Unable to execute '" << cmd << "': " << strerror(errno);
+    LOG(ERROR) << "Unable to execute '" << cmd_str << "': " << strerror(errno);
     return {};
   }
   int64_t pid;
@@ -85,10 +121,10 @@
   return ret;
 }
 
-int FallBackStop() {
+int FallBackStop(const std::set<std::string>& paths) {
   auto exit_code = 1; // Having to fallback is an error
 
-  auto process_groups = GetCandidateProcessGroups();
+  auto process_groups = GetCandidateProcessGroups(paths);
   for (auto pgid: process_groups) {
     LOG(INFO) << "Sending SIGKILL to process group " << pgid;
     auto retval = killpg(pgid, SIGKILL);
@@ -101,37 +137,26 @@
 
   return exit_code;
 }
-}  // anonymous namespace
 
-int main(int argc, char** argv) {
-  ::android::base::InitLogging(argv, android::base::StderrLogger);
-  google::ParseCommandLineFlags(&argc, &argv, true);
-
-  auto config = vsoc::CuttlefishConfig::Get();
-  auto instance = config->ForDefaultInstance();
-  if (!config) {
-    LOG(ERROR) << "Failed to obtain config object";
-    return FallBackStop();
-  }
-
+bool CleanStopInstance(const vsoc::CuttlefishConfig::InstanceSpecific& instance) {
   auto monitor_path = instance.launcher_monitor_socket_path();
   if (monitor_path.empty()) {
     LOG(ERROR) << "No path to launcher monitor found";
-    return FallBackStop();
+    return false;
   }
   auto monitor_socket = cvd::SharedFD::SocketLocalClient(monitor_path.c_str(),
                                                          false, SOCK_STREAM);
   if (!monitor_socket->IsOpen()) {
     LOG(ERROR) << "Unable to connect to launcher monitor at " << monitor_path
                << ": " << monitor_socket->StrError();
-    return FallBackStop();
+    return false;
   }
   auto request = cvd::LauncherAction::kStop;
   auto bytes_sent = monitor_socket->Send(&request, sizeof(request), 0);
   if (bytes_sent < 0) {
     LOG(ERROR) << "Error sending launcher monitor the stop command: "
                << monitor_socket->StrError();
-    return FallBackStop();
+    return false;
   }
   // Perform a select with a timeout to guard against launcher hanging
   cvd::SharedFDSet read_set;
@@ -142,24 +167,53 @@
   if (selected < 0){
     LOG(ERROR) << "Failed communication with the launcher monitor: "
                << strerror(errno);
-    return FallBackStop();
+    return false;
   }
   if (selected == 0) {
     LOG(ERROR) << "Timeout expired waiting for launcher monitor to respond";
-    return FallBackStop();
+    return false;
   }
   cvd::LauncherResponse response;
   auto bytes_recv = monitor_socket->Recv(&response, sizeof(response), 0);
   if (bytes_recv < 0) {
     LOG(ERROR) << "Error receiving response from launcher monitor: "
                << monitor_socket->StrError();
-    return FallBackStop();
+    return false;
   }
   if (response != cvd::LauncherResponse::kSuccess) {
     LOG(ERROR) << "Received '" << static_cast<char>(response)
                << "' response from launcher monitor";
-    return FallBackStop();
+    return false;
   }
-  LOG(INFO) << "Successfully stopped device";
+  LOG(INFO) << "Successfully stopped device " << instance.adb_ip_and_port();
+  return true;
+}
+
+int StopInstance(const vsoc::CuttlefishConfig& config,
+                 const vsoc::CuttlefishConfig::InstanceSpecific& instance) {
+  bool res = CleanStopInstance(instance);
+  if (!res) {
+    return FallBackStop(PathsForInstance(config, instance));
+  }
   return 0;
 }
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv, android::base::StderrLogger);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  auto config = vsoc::CuttlefishConfig::Get();
+  if (!config) {
+    LOG(ERROR) << "Failed to obtain config object";
+    return FallBackStop(FallbackPaths());
+  }
+
+  int ret = 0;
+  for (const auto& instance : config->Instances()) {
+    ret |= StopInstance(*config, instance);
+  }
+
+  return ret;
+}
diff --git a/host/frontend/adb_connector/Android.bp b/host/frontend/adb_connector/Android.bp
index 41fa1f6..c0f04cd 100644
--- a/host/frontend/adb_connector/Android.bp
+++ b/host/frontend/adb_connector/Android.bp
@@ -16,13 +16,13 @@
 cc_binary_host {
     name: "adb_connector",
     srcs: [
+        "adb_connection_maintainer.cpp",
         "main.cpp"
     ],
     header_libs: [
         "cuttlefish_glog",
     ],
     static_libs: [
-        "libadb_connection_maintainer",
         "libgflags",
     ],
     shared_libs: [
diff --git a/host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp b/host/frontend/adb_connector/adb_connection_maintainer.cpp
similarity index 98%
rename from host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp
rename to host/frontend/adb_connector/adb_connection_maintainer.cpp
index 1336951..6b60e34 100644
--- a/host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp
+++ b/host/frontend/adb_connector/adb_connection_maintainer.cpp
@@ -25,7 +25,7 @@
 #include <unistd.h>
 
 #include "common/libs/fs/shared_fd.h"
-#include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h"
+#include "host/frontend/adb_connector/adb_connection_maintainer.h"
 
 namespace {
 
diff --git a/host/libs/adb_connection_maintainer/adb_connection_maintainer.h b/host/frontend/adb_connector/adb_connection_maintainer.h
similarity index 100%
rename from host/libs/adb_connection_maintainer/adb_connection_maintainer.h
rename to host/frontend/adb_connector/adb_connection_maintainer.h
diff --git a/host/frontend/adb_connector/main.cpp b/host/frontend/adb_connector/main.cpp
index 3d3d824..a6f8ebe 100644
--- a/host/frontend/adb_connector/main.cpp
+++ b/host/frontend/adb_connector/main.cpp
@@ -28,8 +28,8 @@
 #include <host/commands/kernel_log_monitor/kernel_log_server.h>
 
 #include "common/libs/fs/shared_fd.h"
+#include "host/frontend/adb_connector/adb_connection_maintainer.h"
 #include "host/libs/config/cuttlefish_config.h"
-#include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h"
 
 DEFINE_string(addresses, "", "Comma-separated list of addresses to "
                              "'adb connect' to");
diff --git a/host/libs/adb_connection_maintainer/Android.bp b/host/libs/adb_connection_maintainer/Android.bp
deleted file mode 100644
index 4a89da3..0000000
--- a/host/libs/adb_connection_maintainer/Android.bp
+++ /dev/null
@@ -1,28 +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.
-
-cc_library_host_static {
-    name: "libadb_connection_maintainer",
-    srcs: [
-        "adb_connection_maintainer.cpp",
-    ],
-    header_libs: [
-        "cuttlefish_glog",
-    ],
-    shared_libs: [
-        "libbase",
-    ],
-    defaults: ["cuttlefish_host_only"],
-}
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 818cb6d..c133a62 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -163,6 +163,7 @@
 
 const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
 const char* const kGpuModeDrmVirgl = "drm_virgl";
+const char* const kGpuModeGfxStream = "gfxstream";
 
 std::string DefaultEnvironmentPath(const char* environment_key,
                                    const char* default_value,
@@ -338,21 +339,21 @@
   SetPath(kVendorRamdiskImagePath, vendor_ramdisk_image_path);
 }
 
-std::vector<std::string> CuttlefishConfig::virtual_disk_paths() const {
+std::vector<std::string> CuttlefishConfig::InstanceSpecific::virtual_disk_paths() const {
   std::vector<std::string> virtual_disks;
-  auto virtual_disks_json_obj = (*dictionary_)[kVirtualDiskPaths];
+  auto virtual_disks_json_obj = (*Dictionary())[kVirtualDiskPaths];
   for (const auto& disk : virtual_disks_json_obj) {
     virtual_disks.push_back(disk.asString());
   }
   return virtual_disks;
 }
-void CuttlefishConfig::set_virtual_disk_paths(
+void CuttlefishConfig::MutableInstanceSpecific::set_virtual_disk_paths(
     const std::vector<std::string>& virtual_disk_paths) {
   Json::Value virtual_disks_json_obj(Json::arrayValue);
   for (const auto& arg : virtual_disk_paths) {
     virtual_disks_json_obj.append(arg);
   }
-  (*dictionary_)[kVirtualDiskPaths] = virtual_disks_json_obj;
+  (*Dictionary())[kVirtualDiskPaths] = virtual_disks_json_obj;
 }
 
 std::string CuttlefishConfig::InstanceSpecific::kernel_log_pipe_name() const {
@@ -843,7 +844,10 @@
 CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
 // Can't use '= default' on the header because the compiler complains of
 // Json::Value being an incomplete type
-CuttlefishConfig::~CuttlefishConfig() {}
+CuttlefishConfig::~CuttlefishConfig() = default;
+
+CuttlefishConfig::CuttlefishConfig(CuttlefishConfig&&) = default;
+CuttlefishConfig& CuttlefishConfig::operator=(CuttlefishConfig&&) = default;
 
 bool CuttlefishConfig::LoadFromFile(const char* file) {
   auto real_file_path = cvd::AbsolutePath(file);
@@ -894,14 +898,27 @@
   return ForCurrentInstance("cvd-");
 }
 
-CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForDefaultInstance() {
-  return MutableInstanceSpecific(this, std::to_string(GetInstance()));
+CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
+  return MutableInstanceSpecific(this, std::to_string(num));
+}
+
+CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstance(int num) const {
+  return InstanceSpecific(this, std::to_string(num));
 }
 
 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForDefaultInstance() const {
   return InstanceSpecific(this, std::to_string(GetInstance()));
 }
 
+std::vector<CuttlefishConfig::InstanceSpecific> CuttlefishConfig::Instances() const {
+  const auto& json = (*dictionary_)[kInstances];
+  std::vector<CuttlefishConfig::InstanceSpecific> instances;
+  for (const auto& name : json.getMemberNames()) {
+    instances.push_back(CuttlefishConfig::InstanceSpecific(this, name));
+  }
+  return instances;
+}
+
 int GetInstance() {
   static int instance_id = InstanceFromEnvironment();
   return instance_id;
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 2ee6135..f78327d 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -18,6 +18,7 @@
 #include <memory>
 #include <string>
 #include <set>
+#include <vector>
 
 namespace Json {
 class Value;
@@ -51,7 +52,9 @@
   static const CuttlefishConfig* Get();
 
   CuttlefishConfig();
+  CuttlefishConfig(CuttlefishConfig&&);
   ~CuttlefishConfig();
+  CuttlefishConfig& operator=(CuttlefishConfig&&);
 
   // Saves the configuration object in a file, it can then be read in other
   // processes by passing the --config_file option.
@@ -135,9 +138,6 @@
   void set_vendor_ramdisk_image_path(const std::string&
     vendor_ramdisk_image_path);
 
-  std::vector<std::string> virtual_disk_paths() const;
-  void set_virtual_disk_paths(const std::vector<std::string>& disk_paths);
-
   bool deprecated_boot_completed() const;
   void set_deprecated_boot_completed(bool deprecated_boot_completed);
 
@@ -259,21 +259,22 @@
   class InstanceSpecific;
   class MutableInstanceSpecific;
 
-  MutableInstanceSpecific ForDefaultInstance();
+  MutableInstanceSpecific ForInstance(int instance_num);
+  InstanceSpecific ForInstance(int instance_num) const;
   InstanceSpecific ForDefaultInstance() const;
 
+  std::vector<InstanceSpecific> Instances() const;
+
   // A view into an existing CuttlefishConfig object for a particular instance.
   class InstanceSpecific {
     const CuttlefishConfig* config_;
     std::string id_;
+    friend InstanceSpecific CuttlefishConfig::ForInstance(int num) const;
     friend InstanceSpecific CuttlefishConfig::ForDefaultInstance() const;
+    friend std::vector<InstanceSpecific> CuttlefishConfig::Instances() const;
 
     InstanceSpecific(const CuttlefishConfig* config, const std::string& id)
         : config_(config), id_(id) {}
-    InstanceSpecific(const InstanceSpecific&) = delete;
-    InstanceSpecific(InstanceSpecific&&) = delete;
-    InstanceSpecific& operator=(const InstanceSpecific&) = delete;
-    InstanceSpecific& operator=(InstanceSpecific&&) = delete;
 
     Json::Value* Dictionary();
     const Json::Value* Dictionary() const;
@@ -290,6 +291,7 @@
     int vsock_guest_cid() const;
     std::string uuid() const;
     std::string instance_name() const;
+    std::vector<std::string> virtual_disk_paths() const;
 
     // Returns the path to a file with the given name in the instance directory..
     std::string PerInstancePath(const char* file_name) const;
@@ -322,14 +324,10 @@
   class MutableInstanceSpecific {
     CuttlefishConfig* config_;
     std::string id_;
-    friend MutableInstanceSpecific CuttlefishConfig::ForDefaultInstance();
+    friend MutableInstanceSpecific CuttlefishConfig::ForInstance(int num);
 
     MutableInstanceSpecific(CuttlefishConfig* config, const std::string& id)
         : config_(config), id_(id) {}
-    MutableInstanceSpecific(const MutableInstanceSpecific&) = delete;
-    MutableInstanceSpecific(MutableInstanceSpecific&&) = delete;
-    MutableInstanceSpecific& operator=(const MutableInstanceSpecific&) = delete;
-    MutableInstanceSpecific& operator=(MutableInstanceSpecific&&) = delete;
 
     Json::Value* Dictionary();
   public:
@@ -344,14 +342,12 @@
     void set_vsock_guest_cid(int vsock_guest_cid);
     void set_uuid(const std::string& uuid);
     void set_instance_dir(const std::string& instance_dir);
+    void set_virtual_disk_paths(const std::vector<std::string>& disk_paths);
   };
 
  private:
   std::unique_ptr<Json::Value> dictionary_;
 
-  InstanceSpecific ForInstance(int instance_num);
-  const InstanceSpecific ForInstance(int instance_num) const;
-
   void SetPath(const std::string& key, const std::string& path);
   bool LoadFromFile(const char* file);
   static CuttlefishConfig* BuildConfigImpl();
@@ -390,4 +386,5 @@
 // GPU modes
 extern const char* const kGpuModeGuestSwiftshader;
 extern const char* const kGpuModeDrmVirgl;
+extern const char* const kGpuModeGfxStream;
 }  // namespace vsoc
diff --git a/host/libs/screen_connector/screen_connector.cpp b/host/libs/screen_connector/screen_connector.cpp
index 906435a..39c0fa3 100644
--- a/host/libs/screen_connector/screen_connector.cpp
+++ b/host/libs/screen_connector/screen_connector.cpp
@@ -26,7 +26,8 @@
 
 ScreenConnector* ScreenConnector::Get(int frames_fd) {
   auto config = vsoc::CuttlefishConfig::Get();
-  if (config->gpu_mode() == vsoc::kGpuModeDrmVirgl) {
+  if (config->gpu_mode() == vsoc::kGpuModeDrmVirgl ||
+      config->gpu_mode() == vsoc::kGpuModeGfxStream) {
     return new WaylandScreenConnector(frames_fd);
   } else if (config->gpu_mode() == vsoc::kGpuModeGuestSwiftshader) {
     return new SocketBasedScreenConnector(frames_fd);
diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh
index 5d88b3f..3eea194 100755
--- a/host/libs/vm_manager/cf_qemu.sh
+++ b/host/libs/vm_manager/cf_qemu.sh
@@ -105,7 +105,7 @@
     bootindex=""
   fi
   args+=(
-    -drive "file=${virtual_disk},format=raw,if=none,id=drive-virtio-disk${virtual_disk_index},aio=threads"
+    -drive "file=${virtual_disk},format=qcow2,if=none,id=drive-virtio-disk${virtual_disk_index},aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk${virtual_disk_index},id=virtio-disk${virtual_disk_index}${bootindex}"
   )
   virtual_disk_index=$((virtual_disk_index + 1))
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 5674a21..63dd3ed 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -84,6 +84,15 @@
         "androidboot.hardware.vulkan=pastel",
     };
   }
+  if (gpu_mode == vsoc::kGpuModeGfxStream) {
+    return {
+        "androidboot.hardware.gralloc=minigbm",
+        "androidboot.hardware.hwcomposer=ranchu",
+        "androidboot.hardware.egl=emulation",
+        "androidboot.hardware.vulkan=ranchu",
+        "androidboot.hardware.gltransport=virtio-gpu-pipe",
+    };
+  }
   return {};
 }
 
@@ -108,8 +117,12 @@
   });
   crosvm_cmd.AddParameter("run");
 
-  if (config_->gpu_mode() == vsoc::kGpuModeDrmVirgl) {
-    crosvm_cmd.AddParameter("--gpu=",
+  auto gpu_mode = config_->gpu_mode();
+
+  if (gpu_mode == vsoc::kGpuModeDrmVirgl ||
+      gpu_mode == vsoc::kGpuModeGfxStream) {
+    crosvm_cmd.AddParameter(gpu_mode == vsoc::kGpuModeGfxStream ?
+                                "--gpu=gfxstream," : "--gpu=",
                             "width=", config_->x_res(), ",",
                             "height=", config_->y_res(), ",",
                             "egl=true,surfaceless=true,glx=false,gles=false");
@@ -122,7 +135,7 @@
   crosvm_cmd.AddParameter("--mem=", config_->memory_mb());
   crosvm_cmd.AddParameter("--cpus=", config_->cpus());
   crosvm_cmd.AddParameter("--params=", kernel_cmdline_);
-  for (const auto& disk : config_->virtual_disk_paths()) {
+  for (const auto& disk : instance.virtual_disk_paths()) {
     crosvm_cmd.AddParameter("--rwdisk=", disk);
   }
   crosvm_cmd.AddParameter("--socket=", GetControlSocketPath(config_));
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 643ffc5..af15f0d 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -140,7 +140,7 @@
   LogAndSetEnv("gdb_flag", config_->gdb_flag());
   LogAndSetEnv("ramdisk_image_path", config_->final_ramdisk_path());
   LogAndSetEnv("kernel_cmdline", kernel_cmdline_);
-  LogAndSetEnv("virtual_disk_paths", JoinString(config_->virtual_disk_paths(),
+  LogAndSetEnv("virtual_disk_paths", JoinString(instance.virtual_disk_paths(),
                                                 ";"));
   LogAndSetEnv("wifi_tap_name", instance.wifi_tap_name());
   LogAndSetEnv("mobile_tap_name", instance.mobile_tap_name());
diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp
index 40fa828..d2810da 100644
--- a/host/libs/vm_manager/vm_manager.cpp
+++ b/host/libs/vm_manager/vm_manager.cpp
@@ -117,7 +117,7 @@
   return true;
 }
 
-bool VmManager::LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands) {
+std::pair<int,int> VmManager::GetLinuxVersion() {
   struct utsname info;
   if (!uname(&info)) {
     char* digit = strtok(info.release, "+.-");
@@ -125,24 +125,57 @@
     if (digit) {
       digit = strtok(NULL, "+.-");
       int minor = atoi(digit);
-      if (major > 4 || (major == 4 && minor >= 8)) {
-        return true;
-      }
+      return std::pair<int,int>{major, minor};
     }
   }
-  LOG(ERROR) << "Kernel version must be >=4.8";
-  config_commands->push_back("# Please upgrade your kernel to >=4.8");
+  LOG(ERROR) << "Failed to detect Linux kernel version";
+  return invalid_linux_version;
+}
+
+bool VmManager::LinuxVersionAtLeast(std::vector<std::string>* config_commands,
+                                    const std::pair<int,int>& version,
+                                    int major, int minor) {
+  if (version.first > major ||
+      (version.first == major && version.second >= minor)) {
+    return true;
+  }
+
+  LOG(ERROR) << "Kernel version must be >=" << major << "." << minor
+             << ", have " << version.first << "." << version.second;
+  config_commands->push_back("# Please upgrade your kernel to >=" +
+                             std::to_string(major) + "." +
+                             std::to_string(minor));
   return false;
 }
 
 bool VmManager::ValidateHostConfiguration(
     std::vector<std::string>* config_commands) const {
+  // if we can't detect the kernel version, just fail
+  auto version = VmManager::GetLinuxVersion();
+  if (version == invalid_linux_version) {
+    return false;
+  }
+
   // the check for cvdnetwork needs to happen even if the user is not in kvm, so
   // we can't just say UserInGroup("kvm") && UserInGroup("cvdnetwork")
-  auto in_kvm = VmManager::UserInGroup("kvm", config_commands);
   auto in_cvdnetwork = VmManager::UserInGroup("cvdnetwork", config_commands);
-  auto linux_ver_4_8 = VmManager::LinuxVersionAtLeast4_8(config_commands);
-  return in_kvm && in_cvdnetwork && linux_ver_4_8;
+
+  // if we're in the virtaccess group this is likely to be a CrOS environment.
+  auto is_cros = cvd::InGroup("virtaccess");
+  if (is_cros) {
+    // relax the minimum kernel requirement slightly, as chromeos-4.4 has the
+    // needed backports to enable vhost_vsock
+    auto linux_ver_4_4 =
+      VmManager::LinuxVersionAtLeast(config_commands, version, 4, 4);
+    return in_cvdnetwork && linux_ver_4_4;
+  } else {
+    // this is regular Linux, so use the Debian group name and be more
+    // conservative with the kernel version check.
+    auto in_kvm = VmManager::UserInGroup("kvm", config_commands);
+    auto linux_ver_4_8 =
+      VmManager::LinuxVersionAtLeast(config_commands, version, 4, 8);
+    return in_cvdnetwork && in_kvm && linux_ver_4_8;
+  }
 }
 
 void VmManager::WithFrontend(bool enabled) {
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index a14ad05..a86218c 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -60,7 +60,12 @@
  protected:
   static bool UserInGroup(const std::string& group,
                           std::vector<std::string>* config_commands);
-  static bool LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands);
+  static constexpr std::pair<int,int> invalid_linux_version =
+    std::pair<int,int>();
+  static std::pair<int,int> GetLinuxVersion();
+  static bool LinuxVersionAtLeast(std::vector<std::string>* config_commands,
+                                  const std::pair<int,int>& version,
+                                  int major, int minor);
 
   const vsoc::CuttlefishConfig* config_;
   VmManager(const vsoc::CuttlefishConfig* config);
diff --git a/host_package.mk b/host_package.mk
index 945784c..71c552f 100644
--- a/host_package.mk
+++ b/host_package.mk
@@ -35,7 +35,7 @@
     aarch64-linux-gnu/libepoxy.so.0 \
     aarch64-linux-gnu/libgbm.so.1 \
     aarch64-linux-gnu/libminijail.so \
-    aarch64-linux-gnu/libvirglrenderer.so.0 \
+    aarch64-linux-gnu/libvirglrenderer.so.1 \
     x86_64-linux-gnu/crosvm \
     x86_64-linux-gnu/libepoxy.so.0 \
     x86_64-linux-gnu/libgbm.so.1 \
diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk
index 4706000..f2a8bea 100644
--- a/shared/BoardConfig.mk
+++ b/shared/BoardConfig.mk
@@ -52,7 +52,7 @@
 
 BOARD_USES_GENERIC_AUDIO := false
 USE_CAMERA_STUB := true
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := false
 
 # Hardware composer configuration
 TARGET_USES_HWC2 := true
@@ -62,6 +62,9 @@
 
 # Make the userdata partition 4.25G to accomodate ASAN and CTS
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 4563402752
+TARGET_USERIMAGES_SPARSE_F2FS_DISABLED := false
+BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE := f2fs
+TARGET_USERIMAGES_USE_F2FS := true
 
 # Cache partition size: 64M
 BOARD_CACHEIMAGE_PARTITION_SIZE := 67108864
diff --git a/shared/auto/OWNERS b/shared/auto/OWNERS
new file mode 100644
index 0000000..53bbd52
--- /dev/null
+++ b/shared/auto/OWNERS
@@ -0,0 +1,3 @@
+# Android Auto leads
+ankitarora@google.com
+egranata@google.com
diff --git a/shared/auto/device.mk b/shared/auto/device.mk
index 30ff594..e0693e5 100644
--- a/shared/auto/device.mk
+++ b/shared/auto/device.mk
@@ -57,7 +57,10 @@
     vendor.rild.libpath=libcuttlefish-ril.so \
 
 # vehicle HAL
-PRODUCT_PACKAGES += android.hardware.automotive.vehicle@2.0-service
+ifeq ($(LOCAL_VHAL_PRODUCT_PACKAGE),)
+    LOCAL_VHAL_PRODUCT_PACKAGE := android.hardware.automotive.vehicle@2.0-service
+endif
+PRODUCT_PACKAGES += $(LOCAL_VHAL_PRODUCT_PACKAGE)
 
 # Broadcast Radio
 PRODUCT_PACKAGES += android.hardware.broadcastradio@2.0-service
diff --git a/shared/config/fstab b/shared/config/fstab
index 1016b62..20685f8 100644
--- a/shared/config/fstab
+++ b/shared/config/fstab
@@ -1,9 +1,9 @@
 boot /boot emmc defaults recoveryonly
 system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
 # Add all non-dynamic partitions except system, after this comment
-/dev/block/by-name/userdata /data ext4 nodev,noatime,nosuid,errors=panic wait,fileencryption=aes-256-xts:aes-256-cts,fsverity
-/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount
+/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid wait,fileencryption=aes-256-xts:aes-256-cts,fsverity
 /dev/block/by-name/cache /cache ext4 nodev,noatime,nosuid,errors=panic wait
+/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount
 /dev/block/by-name/misc /misc emmc defaults defaults
 # Add all dynamic partitions except system, after this comment
 vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
diff --git a/shared/config/fstab.composite b/shared/config/fstab.composite
deleted file mode 100644
index afacfe4..0000000
--- a/shared/config/fstab.composite
+++ /dev/null
@@ -1,13 +0,0 @@
-boot /boot emmc defaults recoveryonly
-system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
-# Add all non-dynamic partitions except system, after this comment
-/dev/block/by-name/userdata /data ext4 nodev,noatime,nosuid,errors=panic wait,fileencryption=aes-256-xts:aes-256-cts,fsverity
-/dev/block/by-name/cache /cache ext4 nodev,noatime,nosuid,errors=panic wait
-/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount
-/dev/block/by-name/misc /misc emmc defaults defaults
-# Add all dynamic partitions except system, after this comment
-vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
-product /product ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
-system_ext /system_ext ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
-/dev/block/zram0 none swap defaults zramsize=75%
-/tmp /sdcard none defaults,bind recoveryonly
diff --git a/shared/config/init.vendor.rc b/shared/config/init.vendor.rc
index eda28df..6052f9d 100644
--- a/shared/config/init.vendor.rc
+++ b/shared/config/init.vendor.rc
@@ -8,7 +8,6 @@
     chown system system /dev/gce
 
     mount tracefs tracefs /sys/kernel/tracing
-    chmod 0755 /sys/kernel/tracing
 
     setprop ro.sf.lcd_density ${ro.boot.lcd_density}
     setprop ro.hardware.egl ${ro.boot.hardware.egl}
diff --git a/shared/config/manifest.xml b/shared/config/manifest.xml
index 6783068..2d728e9 100644
--- a/shared/config/manifest.xml
+++ b/shared/config/manifest.xml
@@ -137,7 +137,7 @@
     <hal format="hidl">
         <name>android.hardware.dumpstate</name>
         <transport>hwbinder</transport>
-        <version>1.0</version>
+        <version>1.1</version>
         <interface>
             <name>IDumpstateDevice</name>
             <instance>default</instance>
diff --git a/shared/config/task_profiles.json b/shared/config/task_profiles.json
index 29bcf30..b883c46 100644
--- a/shared/config/task_profiles.json
+++ b/shared/config/task_profiles.json
@@ -33,12 +33,12 @@
     {
       "Name": "UClampMin",
       "Controller": "cpu",
-      "File": "cpu.util.min"
+      "File": "cpu.uclamp.min"
     },
     {
       "Name": "UClampMax",
       "Controller": "cpu",
-      "File": "cpu.util.max"
+      "File": "cpu.uclamp.max"
     }
   ],
 
diff --git a/shared/device.mk b/shared/device.mk
index c05a1f1..5b1065a 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -17,6 +17,9 @@
 # Enable updating of APEXes
 $(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
 
+# Enable userspace reboot
+$(call inherit-product, $(SRC_TARGET_DIR)/product/userspace_reboot.mk)
+
 PRODUCT_SHIPPING_API_LEVEL := 29
 PRODUCT_BUILD_BOOT_IMAGE := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
@@ -101,7 +104,22 @@
 
 # GL implementation for virgl
 PRODUCT_PACKAGES += \
-    libGLES_mesa
+    libGLES_mesa \
+
+# GL/Vk implementation for gfxstream
+PRODUCT_PACKAGES += \
+    vulkan.ranchu \
+    hwcomposer.ranchu \
+    libandroidemu \
+    libOpenglCodecCommon \
+    libOpenglSystemCommon \
+    libGLESv1_CM_emulation \
+    lib_renderControl_enc \
+    libEGL_emulation \
+    libGLESv2_enc \
+    libvulkan_enc \
+    libGLESv2_emulation \
+    libGLESv1_enc
 
 #
 # Packages for the Vulkan implementation
@@ -109,6 +127,12 @@
 PRODUCT_PACKAGES += \
     vulkan.pastel
 
+#
+# Packages for testing
+#
+PRODUCT_PACKAGES += \
+    aidl_lazy_test_server
+
 DEVICE_PACKAGE_OVERLAYS := device/google/cuttlefish/shared/overlay
 # PRODUCT_AAPT_CONFIG and PRODUCT_AAPT_PREF_CONFIG are intentionally not set to
 # pick up every density resources.
@@ -227,7 +251,7 @@
 # Dumpstate HAL
 #
 PRODUCT_PACKAGES += \
-    android.hardware.dumpstate@1.0-service.cuttlefish
+    android.hardware.dumpstate@1.1-service.cuttlefish
 
 #
 # Camera
diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts
index 9000734..f44f0be 100644
--- a/shared/sepolicy/vendor/file_contexts
+++ b/shared/sepolicy/vendor/file_contexts
@@ -60,7 +60,7 @@
 /vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service-lazy\.clearkey  u:object_r:hal_drm_clearkey_exec:s0
 /vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service\.widevine  u:object_r:hal_drm_widevine_exec:s0
 /vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service-lazy\.widevine  u:object_r:hal_drm_widevine_exec:s0
-/vendor/bin/hw/android\.hardware\.dumpstate@1\.0-service\.cuttlefish  u:object_r:hal_dumpstate_impl_exec:s0
+/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\.neuralnetworks@1\.3-service-sample-.*   u:object_r:hal_neuralnetworks_sample_exec:s0
@@ -86,3 +86,16 @@
 /vendor/lib(64)?/hw/vulkan.pastel.so  u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libcuttlefish_fs.so  u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/vsoc_lib.so  u:object_r:same_process_hal_file:s0
+
+# gfxstream (to be better factored (fewer libraries?))
+/vendor/lib(64)?/hw/vulkan\.ranchu\.so   u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libEGL_emulation\.so          u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libGLESv1_CM_emulation\.so    u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libGLESv2_emulation\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libOpenglCodecCommon\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libOpenglSystemCommon\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/lib_renderControl_enc\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libGLESv1_enc\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libGLESv2_enc\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libvulkan_enc\.so       u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libandroidemu\.so       u:object_r:same_process_hal_file:s0
diff --git a/shared/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts
index 76d034d..36a5a07 100644
--- a/shared/sepolicy/vendor/genfs_contexts
+++ b/shared/sepolicy/vendor/genfs_contexts
@@ -4,9 +4,6 @@
 genfscon sysfs /devices/platform/rtc-test.0/rtc/rtc0/hctosys u:object_r:sysfs_rtc:s0
 genfscon sysfs /devices/platform/rtc-test.1/rtc/rtc1/hctosys u:object_r:sysfs_rtc:s0
 genfscon sysfs /devices/platform/rtc-test.2/rtc/rtc2/hctosys u:object_r:sysfs_rtc:s0
-genfscon sysfs /devices/platform/rtc-test.1/rtc/rtc1/wakeup1  u:object_r:sysfs_wakeup:s0
-genfscon sysfs /devices/platform/rtc-test.1/wakeup/wakeup0  u:object_r:sysfs_wakeup:s0
-genfscon sysfs /devices/platform/rtc-test.2/wakeup/wakeup2 u:object_r:sysfs_wakeup:s0
 genfscon sysfs /devices/pci0000:00/0000:00:04.0/virtio2/net u:object_r:sysfs_net:s0 # qemu buried_eth0 & wlan0
 genfscon sysfs /devices/pci0000:00/0000:00:05.0/virtio3/net u:object_r:sysfs_net:s0 # qemu rmnet0
 genfscon sysfs /devices/pci0000:00/0000:00:07.0/virtio6/net u:object_r:sysfs_net:s0 # crosvm buried_eth0 & wlan0
@@ -16,3 +13,12 @@
 genfscon sysfs /devices/pci0000:00/0000:00:0a.0/subsystem_vendor u:object_r:sysfs_gpu:s0
 genfscon sysfs /devices/pci0000:00/0000:00:0a.0/uevent u:object_r:sysfs_gpu:s0
 genfscon sysfs /devices/pci0000:00/0000:00:0a.0/vendor u:object_r:sysfs_gpu:s0
+
+# TODO(b/148802006): Work around core policy sysfs_wakeup label not working
+# All kernels
+genfscon sysfs /devices/platform/rtc-test.1/wakeup/wakeup0  u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/rtc-test.2/wakeup/wakeup2 u:object_r:sysfs_wakeup:s0
+# Kernels <=5.5
+genfscon sysfs /devices/platform/rtc-test.1/rtc/rtc1/wakeup1  u:object_r:sysfs_wakeup:s0
+# Kernels >5.5
+genfscon sysfs /devices/platform/rtc-test.1/rtc/rtc1/alarmtimer.0.auto/wakeup/wakeup1  u:object_r:sysfs_wakeup:s0
diff --git a/shared/sepolicy/vendor/hal_graphics_composer_default.te b/shared/sepolicy/vendor/hal_graphics_composer_default.te
index 6b89710..c3a7cab 100644
--- a/shared/sepolicy/vendor/hal_graphics_composer_default.te
+++ b/shared/sepolicy/vendor/hal_graphics_composer_default.te
@@ -1,3 +1,4 @@
+hal_client_domain(hal_graphics_composer_default, hal_graphics_allocator);
 vndbinder_use(hal_graphics_composer_default)
 
 allow hal_graphics_composer_default self:netlink_kobject_uevent_socket { bind create read };
diff --git a/tools/create_base_image_gce.sh b/tools/create_base_image_gce.sh
index 09443e3..7c693c5 100755
--- a/tools/create_base_image_gce.sh
+++ b/tools/create_base_image_gce.sh
@@ -55,6 +55,7 @@
 sudo chroot /mnt/image /usr/bin/apt install -y openjdk-11-jre
 sudo chroot /mnt/image /usr/bin/apt install -y unzip bzip2 lzop
 sudo chroot /mnt/image /usr/bin/apt install -y aapt
+sudo chroot /mnt/image /usr/bin/apt install -y screen # needed by tradefed
 
 sudo chroot /mnt/image /usr/bin/find /home -ls
 
diff --git a/vsoc_arm64/auto/OWNERS b/vsoc_arm64/auto/OWNERS
new file mode 100644
index 0000000..53bbd52
--- /dev/null
+++ b/vsoc_arm64/auto/OWNERS
@@ -0,0 +1,3 @@
+# Android Auto leads
+ankitarora@google.com
+egranata@google.com
diff --git a/vsoc_x86/auto/OWNERS b/vsoc_x86/auto/OWNERS
new file mode 100644
index 0000000..53bbd52
--- /dev/null
+++ b/vsoc_x86/auto/OWNERS
@@ -0,0 +1,3 @@
+# Android Auto leads
+ankitarora@google.com
+egranata@google.com