Merge "Improve error messages around cvd config loading" into main am: 4a927bc53a

Original change: https://android-review.googlesource.com/c/device/google/cuttlefish/+/2744826

Change-Id: Ic46969003897134e9376fc7a9abb84c0ea11aca7
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index 0b60421..629b2a3 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -30,6 +30,9 @@
 	aosp_cf_riscv64_wear:$(LOCAL_DIR)/vsoc_riscv64/wear/aosp_cf.mk \
 	aosp_cf_riscv64_phone:$(LOCAL_DIR)/vsoc_riscv64/phone/aosp_cf.mk \
 	aosp_cf_x86_64_auto:$(LOCAL_DIR)/vsoc_x86_64_only/auto/aosp_cf.mk \
+	aosp_cf_x86_64_auto_md:$(LOCAL_DIR)/vsoc_x86_64_only/auto_md/aosp_cf.mk \
+	aosp_cf_x86_64_auto_mdnd:$(LOCAL_DIR)/vsoc_x86_64_only/auto_mdnd/aosp_cf.mk \
+	aosp_cf_x86_64_auto_portrait:$(LOCAL_DIR)/vsoc_x86_64_only/auto_portrait/aosp_cf.mk \
 	aosp_cf_x86_64_pc:$(LOCAL_DIR)/vsoc_x86_64_only/pc/aosp_cf.mk \
 	aosp_cf_x86_64_phone:$(LOCAL_DIR)/vsoc_x86_64/phone/aosp_cf.mk \
 	aosp_cf_x86_64_phone_vendor:$(LOCAL_DIR)/vsoc_x86_64/phone/aosp_cf_vendor.mk \
@@ -58,6 +61,7 @@
 	aosp_cf_x86_64_phone-userdebug \
 	aosp_cf_x86_64_foldable-userdebug \
 	aosp_cf_x86_64_auto-userdebug \
+	aosp_cf_x86_64_auto_mdnd-userdebug \
 	aosp_cf_x86_phone-userdebug \
 	aosp_cf_x86_tv-userdebug \
 	aosp_cf_x86_64_tv-userdebug
diff --git a/apex/com.google.cf.rild/Android.bp b/apex/com.google.cf.rild/Android.bp
index 9e237b5..aee3fac 100644
--- a/apex/com.google.cf.rild/Android.bp
+++ b/apex/com.google.cf.rild/Android.bp
@@ -47,6 +47,7 @@
     prebuilts: [
         "android.hardware.telephony.gsm.prebuilt.xml",
         "android.hardware.telephony.ims.prebuilt.xml",
+        "android.hardware.telephony.satellite.prebuilt.xml",
         "com.google.cf.rild.rc",
         "ld.config.txt",
     ],
diff --git a/build/Android.bp b/build/Android.bp
index 7bb0a25..a9d3722 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -46,7 +46,6 @@
 }
 
 cvd_host_tools = [
-    "android.hardware.automotive.vehicle@2.0-virtualization-grpc-server",
     "adb",
     "adb_connector",
     "allocd",
diff --git a/default-permissions.xml b/default-permissions.xml
index 2d5020a..6a7c91b 100644
--- a/default-permissions.xml
+++ b/default-permissions.xml
@@ -54,8 +54,6 @@
         <permission name="android.permission.READ_CALL_LOG" fixed="false"/>
         <permission name="android.permission.WRITE_CALL_LOG" fixed="false"/>
         <!-- Used to set up a Wi-Fi P2P network -->
-        <!-- TODO(b/231966826): Remove the location permission after Restore targets to T. -->
-        <permission name="android.permission.ACCESS_FINE_LOCATION" fixed="false"/>
         <permission name="android.permission.NEARBY_WIFI_DEVICES" fixed="false"/>
         <!-- Notifications -->
         <permission name="android.permission.POST_NOTIFICATIONS" fixed="false"/>
diff --git a/guest/hals/ril/reference-libril/Android.bp b/guest/hals/ril/reference-libril/Android.bp
index bf7d95b..de07522 100644
--- a/guest/hals/ril/reference-libril/Android.bp
+++ b/guest/hals/ril/reference-libril/Android.bp
@@ -24,6 +24,11 @@
         "-Wno-unused-parameter",
     ],
     srcs: [
+        "RefRadioSim.cpp",
+        "RefRadioModem.cpp",
+        "RefRadioIms.cpp",
+        "RefImsMedia.cpp",
+        "RefImsMediaSession.cpp",
         "RefRadioNetwork.cpp",
         "ril.cpp",
         "RilSapSocket.cpp",
@@ -38,14 +43,16 @@
     ],
     shared_libs: [
         "android.hardware.radio-library.compat",
-        "android.hardware.radio.config-V1-ndk",
-        "android.hardware.radio.data-V1-ndk",
-        "android.hardware.radio.messaging-V1-ndk",
-        "android.hardware.radio.modem-V1-ndk",
-        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.config-V2-ndk",
+        "android.hardware.radio.data-V2-ndk",
+        "android.hardware.radio.ims-V1-ndk",
+        "android.hardware.radio.ims.media-V1-ndk",
+        "android.hardware.radio.messaging-V2-ndk",
+        "android.hardware.radio.modem-V2-ndk",
+        "android.hardware.radio.network-V2-ndk",
         "android.hardware.radio.sap-V1-ndk",
-        "android.hardware.radio.sim-V1-ndk",
-        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio.sim-V2-ndk",
+        "android.hardware.radio.voice-V2-ndk",
         "android.hardware.radio@1.0",
         "android.hardware.radio@1.1",
         "android.hardware.radio@1.2",
@@ -75,6 +82,6 @@
 filegroup {
     name: "libril-modem-lib-manifests",
     srcs: [
-        "android.hardware.radio@2.0.xml",
+        "android.hardware.radio@2.1.xml",
     ],
 }
diff --git a/guest/hals/ril/reference-libril/RefImsMedia.cpp b/guest/hals/ril/reference-libril/RefImsMedia.cpp
new file mode 100644
index 0000000..41b0360
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefImsMedia.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RefImsMedia.h"
+
+namespace cf::ril {
+
+using ::ndk::ScopedAStatus;
+using namespace ::aidl::android::hardware::radio::ims::media;
+constexpr auto ok = &ScopedAStatus::ok;
+std::shared_ptr<IImsMediaListener> mediaListener;
+
+ScopedAStatus RefImsMedia::setListener(
+        const std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaListener>&
+                in_mediaListener) {
+    mediaListener = in_mediaListener;
+    return ok();
+}
+ScopedAStatus RefImsMedia::openSession(
+        int32_t in_sessionId,
+        const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& in_localEndPoint,
+        const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) {
+    std::shared_ptr<IImsMediaSession> session =
+            ndk::SharedRefBase::make<RefImsMediaSession>(mContext, mHal1_5, mCallbackManager);
+
+    mediaListener->onOpenSessionSuccess(in_sessionId, session);
+    return ok();
+}
+ScopedAStatus RefImsMedia::closeSession(int32_t in_sessionId) {
+    mediaListener->onSessionClosed(in_sessionId);
+    return ok();
+}
+
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefImsMedia.h b/guest/hals/ril/reference-libril/RefImsMedia.h
new file mode 100644
index 0000000..619b321
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefImsMedia.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <libradiocompat/RadioImsMedia.h>
+#include <libradiocompat/RadioImsMediaSession.h>
+
+namespace cf::ril {
+
+class RefImsMedia : public android::hardware::radio::compat::RadioImsMedia {
+  public:
+    using android::hardware::radio::compat::RadioImsMedia::RadioImsMedia;
+
+    ::ndk::ScopedAStatus setListener(
+            const std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaListener>&
+                    in_mediaListener) override;
+    ::ndk::ScopedAStatus openSession(
+            int32_t in_sessionId,
+            const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& in_localEndPoint,
+            const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+    ::ndk::ScopedAStatus closeSession(int32_t in_sessionId) override;
+};
+
+class RefImsMediaSession : public android::hardware::radio::compat::RadioImsMediaSession {
+  public:
+    using android::hardware::radio::compat::RadioImsMediaSession::RadioImsMediaSession;
+
+    ::ndk::ScopedAStatus setListener(
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::ims::media::IImsMediaSessionListener>&
+                    in_sessionListener) override;
+    ::ndk::ScopedAStatus modifySession(
+            const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+    ::ndk::ScopedAStatus sendDtmf(char16_t in_dtmfDigit, int32_t in_duration) override;
+    ::ndk::ScopedAStatus startDtmf(char16_t in_dtmfDigit) override;
+    ::ndk::ScopedAStatus stopDtmf() override;
+    ::ndk::ScopedAStatus sendHeaderExtension(
+            const std::vector<::aidl::android::hardware::radio::ims::media::RtpHeaderExtension>&
+                    in_extensions) override;
+    ::ndk::ScopedAStatus setMediaQualityThreshold(
+            const ::aidl::android::hardware::radio::ims::media::MediaQualityThreshold& in_threshold)
+            override;
+};
+
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefImsMediaSession.cpp b/guest/hals/ril/reference-libril/RefImsMediaSession.cpp
new file mode 100644
index 0000000..aeb7d9d
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefImsMediaSession.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RefImsMedia.h"
+
+namespace cf::ril {
+
+using ::ndk::ScopedAStatus;
+using namespace ::aidl::android::hardware::radio::ims::media;
+constexpr auto ok = &ScopedAStatus::ok;
+std::shared_ptr<IImsMediaSessionListener> mediaSessionListener;
+
+ScopedAStatus RefImsMediaSession::setListener(
+        const std::shared_ptr<
+                ::aidl::android::hardware::radio::ims::media::IImsMediaSessionListener>&
+                in_sessionListener) {
+    mediaSessionListener = in_sessionListener;
+    return ok();
+}
+
+ScopedAStatus RefImsMediaSession::modifySession(
+        const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) {
+    mediaSessionListener->onModifySessionResponse(
+            in_config, ::aidl::android::hardware::radio::ims::media::RtpError::NONE);
+    return ok();
+}
+
+ScopedAStatus RefImsMediaSession::sendDtmf(char16_t in_dtmfDigit, int32_t in_duration) {
+    return ok();
+}
+ScopedAStatus RefImsMediaSession::startDtmf(char16_t in_dtmfDigit) {
+    return ok();
+}
+ScopedAStatus RefImsMediaSession::stopDtmf() {
+    return ok();
+}
+ScopedAStatus RefImsMediaSession::sendHeaderExtension(
+        const std::vector<::aidl::android::hardware::radio::ims::media::RtpHeaderExtension>&
+                in_extensions) {
+    return ok();
+}
+ScopedAStatus RefImsMediaSession::setMediaQualityThreshold(
+        const ::aidl::android::hardware::radio::ims::media::MediaQualityThreshold& in_threshold) {
+    return ok();
+}
+
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioIms.cpp b/guest/hals/ril/reference-libril/RefRadioIms.cpp
new file mode 100644
index 0000000..d9b09fe
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioIms.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RefRadioIms.h"
+
+namespace cf::ril {
+
+using ::ndk::ScopedAStatus;
+using namespace ::aidl::android::hardware::radio;
+constexpr auto ok = &ScopedAStatus::ok;
+
+static RadioResponseInfo responseInfo(int32_t serial) {
+    return {
+            .type = RadioResponseType::SOLICITED,
+            .serial = serial,
+            .error = RadioError::NONE,
+    };
+}
+
+ScopedAStatus RefRadioIms::setSrvccCallInfo(
+        int32_t serial,
+        const std::vector<::aidl::android::hardware::radio::ims::SrvccCall>& srvccCalls) {
+    respond()->setSrvccCallInfoResponse(responseInfo(serial));
+    return ok();
+}
+ScopedAStatus RefRadioIms::updateImsRegistrationInfo(
+        int32_t serial,
+        const ::aidl::android::hardware::radio::ims::ImsRegistration& imsRegistration) {
+    respond()->updateImsRegistrationInfoResponse(responseInfo(serial));
+    return ok();
+}
+ScopedAStatus RefRadioIms::startImsTraffic(
+        int32_t serial, int32_t token,
+        ::aidl::android::hardware::radio::ims::ImsTrafficType imsTrafficType,
+        ::aidl::android::hardware::radio::AccessNetwork accessNetworkType,
+        ::aidl::android::hardware::radio::ims::ImsCall::Direction trafficDirection) {
+    respond()->startImsTrafficResponse(responseInfo(serial), {});
+    return ok();
+}
+ScopedAStatus RefRadioIms::stopImsTraffic(int32_t serial, int32_t token) {
+    respond()->stopImsTrafficResponse(responseInfo(serial));
+    return ok();
+}
+ScopedAStatus RefRadioIms::triggerEpsFallback(
+        int32_t serial, ::aidl::android::hardware::radio::ims::EpsFallbackReason reason) {
+    respond()->triggerEpsFallbackResponse(responseInfo(serial));
+    return ok();
+}
+ScopedAStatus RefRadioIms::sendAnbrQuery(
+        int32_t serial, ::aidl::android::hardware::radio::ims::ImsStreamType mediaType,
+        ::aidl::android::hardware::radio::ims::ImsStreamDirection direction,
+        int32_t bitsPerSecond) {
+    respond()->sendAnbrQueryResponse(responseInfo(serial));
+    return ok();
+}
+ScopedAStatus RefRadioIms::updateImsCallStatus(
+        int32_t serial,
+        const std::vector<::aidl::android::hardware::radio::ims::ImsCall>& imsCalls) {
+    respond()->updateImsCallStatusResponse(responseInfo(serial));
+    return ok();
+}
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioIms.h b/guest/hals/ril/reference-libril/RefRadioIms.h
new file mode 100644
index 0000000..3202971
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioIms.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <libradiocompat/RadioIms.h>
+
+namespace cf::ril {
+
+class RefRadioIms : public android::hardware::radio::compat::RadioIms {
+  public:
+    using android::hardware::radio::compat::RadioIms::RadioIms;
+
+    ::ndk::ScopedAStatus setSrvccCallInfo(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::ims::SrvccCall>& srvccCalls)
+            override;
+    ::ndk::ScopedAStatus updateImsRegistrationInfo(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::ims::ImsRegistration& imsRegistration) override;
+    ::ndk::ScopedAStatus startImsTraffic(
+            int32_t serial, int32_t token,
+            ::aidl::android::hardware::radio::ims::ImsTrafficType imsTrafficType,
+            ::aidl::android::hardware::radio::AccessNetwork accessNetworkType,
+            ::aidl::android::hardware::radio::ims::ImsCall::Direction trafficDirection) override;
+    ::ndk::ScopedAStatus stopImsTraffic(int32_t serial, int32_t token) override;
+    ::ndk::ScopedAStatus triggerEpsFallback(
+            int32_t serial,
+            ::aidl::android::hardware::radio::ims::EpsFallbackReason reason) override;
+    ::ndk::ScopedAStatus sendAnbrQuery(
+            int32_t serial, ::aidl::android::hardware::radio::ims::ImsStreamType mediaType,
+            ::aidl::android::hardware::radio::ims::ImsStreamDirection direction,
+            int32_t bitsPerSecond) override;
+    ::ndk::ScopedAStatus updateImsCallStatus(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::ims::ImsCall>& imsCalls) override;
+};
+
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioModem.cpp b/guest/hals/ril/reference-libril/RefRadioModem.cpp
new file mode 100644
index 0000000..867c8f0
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioModem.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RefRadioModem.h"
+#include "ril_service.h"
+
+using ::android::hardware::hidl_string;
+
+namespace cf::ril {
+
+    using ::ndk::ScopedAStatus;
+    using namespace ::aidl::android::hardware::radio;
+    constexpr auto ok = &ScopedAStatus::ok;
+
+    static RadioResponseInfo responseInfo(int32_t serial, RadioError error = RadioError::NONE) {
+        return {
+                .type = RadioResponseType::SOLICITED,
+                .serial = serial,
+                .error = error,
+        };
+    }
+
+    hidl_string convertCharPtrToHidlString(const char *ptr) {
+        hidl_string ret;
+        if (ptr != NULL) {
+            ret.setToExternal(ptr, strlen(ptr));
+        }
+        return ret;
+    }
+
+    ScopedAStatus RefRadioModem::getImei(int32_t serial) {
+        ::aidl::android::hardware::radio::modem::ImeiInfo imeiInfo = {};
+        imeiInfo.type = (::aidl::android::hardware::radio::modem::ImeiInfo::ImeiType) 1;
+        imeiInfo.imei = convertCharPtrToHidlString("867400022047199");
+        imeiInfo.svn = convertCharPtrToHidlString("01");
+        respond()->getImeiResponse(responseInfo(serial), imeiInfo);
+        return ok();
+    }
+}
\ No newline at end of file
diff --git a/guest/hals/ril/reference-libril/RefRadioModem.h b/guest/hals/ril/reference-libril/RefRadioModem.h
new file mode 100644
index 0000000..a0a20b1
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioModem.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <libradiocompat/RadioModem.h>
+
+namespace cf::ril {
+
+class RefRadioModem : public android::hardware::radio::compat::RadioModem {
+    public:
+        using android::hardware::radio::compat::RadioModem::RadioModem;
+
+         ::ndk::ScopedAStatus getImei(int32_t serial) override;
+    };
+}
diff --git a/guest/hals/ril/reference-libril/RefRadioNetwork.cpp b/guest/hals/ril/reference-libril/RefRadioNetwork.cpp
index 4f39944..407efaa 100644
--- a/guest/hals/ril/reference-libril/RefRadioNetwork.cpp
+++ b/guest/hals/ril/reference-libril/RefRadioNetwork.cpp
@@ -47,4 +47,46 @@
     return ok();
 }
 
+ScopedAStatus RefRadioNetwork::setEmergencyMode(int32_t serial,
+                                                network::EmergencyMode emergencyMode) {
+    network::EmergencyRegResult regState;
+    respond()->setEmergencyModeResponse(responseInfo(serial), regState);
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::triggerEmergencyNetworkScan(
+        int32_t serial, const network::EmergencyNetworkScanTrigger& request) {
+    respond()->triggerEmergencyNetworkScanResponse(responseInfo(serial));
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::exitEmergencyMode(int32_t serial) {
+    respond()->exitEmergencyModeResponse(responseInfo(serial));
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::cancelEmergencyNetworkScan(int32_t serial, bool resetScan) {
+    respond()->cancelEmergencyNetworkScanResponse(responseInfo(serial));
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::isN1ModeEnabled(int32_t serial) {
+    respond()->isN1ModeEnabledResponse(responseInfo(serial), false);
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::setN1ModeEnabled(int32_t serial, bool enable) {
+    respond()->setN1ModeEnabledResponse(responseInfo(serial));
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) {
+    respond()->setNullCipherAndIntegrityEnabledResponse(responseInfo(serial));
+    return ok();
+}
+
+ScopedAStatus RefRadioNetwork::isNullCipherAndIntegrityEnabled(int32_t serial) {
+    respond()->isNullCipherAndIntegrityEnabledResponse(responseInfo(serial), true);
+    return ok();
+}
 }  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioNetwork.h b/guest/hals/ril/reference-libril/RefRadioNetwork.h
index 5f16b14..c99bf18 100644
--- a/guest/hals/ril/reference-libril/RefRadioNetwork.h
+++ b/guest/hals/ril/reference-libril/RefRadioNetwork.h
@@ -30,6 +30,26 @@
             int32_t serial,
             ::aidl::android::hardware::radio::network::UsageSetting usageSetting) override;
     ::ndk::ScopedAStatus getUsageSetting(int32_t serial) override;
+
+    ::ndk::ScopedAStatus setEmergencyMode(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::EmergencyMode emergencyMode) override;
+
+    ::ndk::ScopedAStatus triggerEmergencyNetworkScan(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::network::EmergencyNetworkScanTrigger& request)
+            override;
+
+    ::ndk::ScopedAStatus exitEmergencyMode(int32_t serial) override;
+
+    ::ndk::ScopedAStatus cancelEmergencyNetworkScan(int32_t serial, bool resetScan) override;
+
+    ::ndk::ScopedAStatus isN1ModeEnabled(int32_t serial) override;
+
+    ::ndk::ScopedAStatus setN1ModeEnabled(int32_t serial, bool enable) override;
+
+    ::ndk::ScopedAStatus setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) override;
+    ::ndk::ScopedAStatus isNullCipherAndIntegrityEnabled(int32_t serial) override;
 };
 
 }  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioSim.cpp b/guest/hals/ril/reference-libril/RefRadioSim.cpp
new file mode 100644
index 0000000..56ce6a1
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioSim.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RefRadioSim.h"
+#include "ril_service.h"
+
+namespace cf::ril {
+
+using ::ndk::ScopedAStatus;
+using namespace ::aidl::android::hardware::radio;
+constexpr auto ok = &ScopedAStatus::ok;
+
+static RadioResponseInfo responseInfo(int32_t serial, RadioError error = RadioError::NONE) {
+    return {
+            .type = RadioResponseType::SOLICITED,
+            .serial = serial,
+            .error = error,
+    };
+}
+
+ScopedAStatus RefRadioSim::iccCloseLogicalChannelWithSessionInfo(
+        int32_t serial, const ::aidl::android::hardware::radio::sim::SessionInfo& sessionInfo) {
+    if (sessionInfo.sessionId == 0) {
+        respond()->iccCloseLogicalChannelWithSessionInfoResponse(
+                responseInfo(serial, RadioError::INVALID_ARGUMENTS));
+        return ok();
+    }
+    // fallback on the deprecated iccCloseLogicalChannel function for
+    // actual channel close functionality
+    return iccCloseLogicalChannel(serial, sessionInfo.sessionId);
+}
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/RefRadioSim.h b/guest/hals/ril/reference-libril/RefRadioSim.h
new file mode 100644
index 0000000..5608639
--- /dev/null
+++ b/guest/hals/ril/reference-libril/RefRadioSim.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <libradiocompat/RadioSim.h>
+
+namespace cf::ril {
+
+class RefRadioSim : public android::hardware::radio::compat::RadioSim {
+  public:
+    using android::hardware::radio::compat::RadioSim::RadioSim;
+
+    ::ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfo(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::SessionInfo& SessionInfo) override;
+};
+}  // namespace cf::ril
diff --git a/guest/hals/ril/reference-libril/android.hardware.radio@2.0.xml b/guest/hals/ril/reference-libril/android.hardware.radio@2.0.xml
index de159b1..8501dec 100644
--- a/guest/hals/ril/reference-libril/android.hardware.radio@2.0.xml
+++ b/guest/hals/ril/reference-libril/android.hardware.radio@2.0.xml
@@ -20,10 +20,6 @@
         <fqname>IRadioNetwork/slot1</fqname>
     </hal>
     <hal format="aidl">
-        <name>android.hardware.radio.sap</name>
-        <fqname>ISap/slot1</fqname>
-    </hal>
-    <hal format="aidl">
         <name>android.hardware.radio.sim</name>
         <fqname>IRadioSim/slot1</fqname>
     </hal>
diff --git a/guest/hals/ril/reference-libril/android.hardware.radio@2.1.xml b/guest/hals/ril/reference-libril/android.hardware.radio@2.1.xml
new file mode 100644
index 0000000..0ffa0d7
--- /dev/null
+++ b/guest/hals/ril/reference-libril/android.hardware.radio@2.1.xml
@@ -0,0 +1,49 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.radio.config</name>
+        <version>2</version>
+        <fqname>IRadioConfig/default</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.data</name>
+        <version>2</version>
+        <fqname>IRadioData/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.ims</name>
+        <fqname>IRadioIms/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.ims.media</name>
+        <fqname>IImsMedia/default</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.messaging</name>
+        <version>2</version>
+        <fqname>IRadioMessaging/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.modem</name>
+        <version>2</version>
+        <fqname>IRadioModem/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.network</name>
+        <version>2</version>
+        <fqname>IRadioNetwork/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.sim</name>
+        <version>2</version>
+        <fqname>IRadioSim/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.sap</name>
+        <fqname>ISap/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.voice</name>
+        <version>2</version>
+        <fqname>IRadioVoice/slot1</fqname>
+    </hal>
+</manifest>
diff --git a/guest/hals/ril/reference-libril/ril_service.cpp b/guest/hals/ril/reference-libril/ril_service.cpp
index 301120d..dd8c861 100644
--- a/guest/hals/ril/reference-libril/ril_service.cpp
+++ b/guest/hals/ril/reference-libril/ril_service.cpp
@@ -16,6 +16,10 @@
 
 #define LOG_TAG "RILC"
 
+#include "RefRadioSim.h"
+#include "RefImsMedia.h"
+#include "RefRadioIms.h"
+#include "RefRadioModem.h"
 #include "RefRadioNetwork.h"
 
 #include <android-base/logging.h>
@@ -27,6 +31,8 @@
 #include <android/hardware/radio/1.6/types.h>
 #include <libradiocompat/CallbackManager.h>
 #include <libradiocompat/RadioData.h>
+#include <libradiocompat/RadioIms.h>
+#include <libradiocompat/RadioImsMedia.h>
 #include <libradiocompat/RadioMessaging.h>
 #include <libradiocompat/RadioModem.h>
 #include <libradiocompat/RadioSim.h>
@@ -13439,14 +13445,17 @@
         publishRadioHal<cf::ril::RefRadioNetwork>(context, radioHidl, callbackMgr, slot);
         publishRadioHal<compat::RadioSim>(context, radioHidl, callbackMgr, slot);
         publishRadioHal<compat::RadioVoice>(context, radioHidl, callbackMgr, slot);
-
+        publishRadioHal<cf::ril::RefRadioIms>(context, radioHidl, callbackMgr, slot);
+        publishRadioHal<cf::ril::RefImsMedia>(context, radioHidl, callbackMgr,
+                                              std::string("default"));
+        publishRadioHal<cf::ril::RefRadioModem>(context, radioHidl, callbackMgr, slot);
+        publishRadioHal<cf::ril::RefRadioSim>(context, radioHidl, callbackMgr, slot);
         RLOGD("registerService: OemHook is enabled = %s", kOemHookEnabled ? "true" : "false");
         if (kOemHookEnabled) {
             oemHookService[i] = new OemHookImpl;
             oemHookService[i]->mSlotId = i;
             // status = oemHookService[i]->registerAsService(serviceNames[i]);
         }
-
         ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
         CHECK_EQ(ret, 0);
     }
diff --git a/guest/services/cf_satellite_service/Android.bp b/guest/services/cf_satellite_service/Android.bp
new file mode 100644
index 0000000..770c68b
--- /dev/null
+++ b/guest/services/cf_satellite_service/Android.bp
@@ -0,0 +1,43 @@
+// Copyright 2023 Google Inc. All Rights Reserved.
+//
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "CFSatelliteService-core",
+    srcs: [
+        "src/**/*.java",
+    ],
+    static_libs: [
+        "android-support-annotations",
+    ],
+    libs: [
+        "telephony-common",
+    ],
+}
+
+android_app {
+    name: "CFSatelliteService",
+    system_ext_specific: true,
+    platform_apis: true,
+    manifest: "AndroidManifest.xml",
+    static_libs: [
+        "CFSatelliteService-core",
+    ],
+    owner: "google",
+    privileged: true,
+    certificate: "platform",
+}
diff --git a/guest/services/cf_satellite_service/AndroidManifest.xml b/guest/services/cf_satellite_service/AndroidManifest.xml
new file mode 100644
index 0000000..17ff714
--- /dev/null
+++ b/guest/services/cf_satellite_service/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          package="com.google.android.telephony.satellite">
+    <application>
+        <service android:name=".CFSatelliteService"
+                 android:exported="true"
+                 android:directBootAware="true"
+                 android:persistent="true"
+                 android:permission="android.permission.BIND_SATELLITE_SERVICE">
+            <intent-filter>
+                <action android:name="android.telephony.satellite.SatelliteService" />
+            </intent-filter>
+        </service>
+    </application>
+</manifest>
diff --git a/guest/services/cf_satellite_service/src/com/google/android/telephony/satellite/CFSatelliteService.java b/guest/services/cf_satellite_service/src/com/google/android/telephony/satellite/CFSatelliteService.java
new file mode 100644
index 0000000..db9cce1
--- /dev/null
+++ b/guest/services/cf_satellite_service/src/com/google/android/telephony/satellite/CFSatelliteService.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package com.google.android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
+import android.telephony.satellite.stub.ISatelliteListener;
+import android.telephony.satellite.stub.NTRadioTechnology;
+import android.telephony.satellite.stub.PointingInfo;
+import android.telephony.satellite.stub.SatelliteCapabilities;
+import android.telephony.satellite.stub.SatelliteDatagram;
+import android.telephony.satellite.stub.SatelliteError;
+import android.telephony.satellite.stub.SatelliteImplBase;
+import android.telephony.satellite.stub.SatelliteModemState;
+import android.telephony.satellite.stub.SatelliteService;
+
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.util.FunctionalUtils;
+import com.android.telephony.Rlog;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+public class CFSatelliteService extends SatelliteImplBase {
+    private static final String TAG = "CFSatelliteService";
+
+    // Hardcoded values below
+    private static final int SATELLITE_ALWAYS_VISIBLE = 0;
+    /** SatelliteCapabilities constant indicating that the radio technology is proprietary. */
+    private static final int[] SUPPORTED_RADIO_TECHNOLOGIES =
+            new int[] {NTRadioTechnology.PROPRIETARY};
+    /** SatelliteCapabilities constant indicating that pointing to satellite is required. */
+    private static final boolean POINTING_TO_SATELLITE_REQUIRED = true;
+    /** SatelliteCapabilities constant indicating the maximum number of characters per datagram. */
+    private static final int MAX_BYTES_PER_DATAGRAM = 339;
+
+    @NonNull private final Map<IBinder, ISatelliteListener> mListeners = new HashMap<>();
+
+    private boolean mIsCommunicationAllowedInLocation;
+    private boolean mIsEnabled;
+    private boolean mIsProvisioned;
+    private boolean mIsSupported;
+    private int mModemState;
+
+    /**
+     * Create CFSatelliteService using the Executor specified for methods being called from
+     * the framework.
+     *
+     * @param executor The executor for the framework to use when executing satellite methods.
+     */
+    public CFSatelliteService(@NonNull Executor executor) {
+        super(executor);
+        mIsCommunicationAllowedInLocation = true;
+        mIsEnabled = false;
+        mIsProvisioned = false;
+        mIsSupported = true;
+        mModemState = SatelliteModemState.SATELLITE_MODEM_STATE_OFF;
+    }
+
+    /**
+     * Zero-argument constructor to prevent service binding exception.
+     */
+    public CFSatelliteService() {
+        this(Runnable::run);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SatelliteService.SERVICE_INTERFACE.equals(intent.getAction())) {
+            logd("CFSatelliteService bound");
+            return new CFSatelliteService().getBinder();
+        }
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        logd("onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        logd("onDestroy");
+    }
+
+    @Override
+    public void setSatelliteListener(@NonNull ISatelliteListener listener) {
+        logd("setSatelliteListener");
+        mListeners.put(listener.asBinder(), listener);
+    }
+
+    @Override
+    public void requestSatelliteListeningEnabled(boolean enable, int timeout,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("requestSatelliteListeningEnabled");
+        if (!verifySatelliteModemState(errorCallback)) {
+            return;
+        }
+        if (enable) {
+            updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_LISTENING);
+        } else {
+            updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE);
+        }
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("requestSatelliteEnabled");
+        if (enableSatellite) {
+            enableSatellite(errorCallback);
+        } else {
+            disableSatellite(errorCallback);
+        }
+    }
+
+    private void enableSatellite(@NonNull IIntegerConsumer errorCallback) {
+        mIsEnabled = true;
+        updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE);
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    private void disableSatellite(@NonNull IIntegerConsumer errorCallback) {
+        mIsEnabled = false;
+        updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_OFF);
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void requestIsSatelliteEnabled(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteEnabled");
+        runWithExecutor(() -> callback.accept(mIsEnabled));
+    }
+
+    @Override
+    public void requestIsSatelliteSupported(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteSupported");
+        runWithExecutor(() -> callback.accept(mIsSupported));
+    }
+
+    @Override
+    public void requestSatelliteCapabilities(@NonNull IIntegerConsumer errorCallback,
+            @NonNull ISatelliteCapabilitiesConsumer callback) {
+        logd("requestSatelliteCapabilities");
+        SatelliteCapabilities capabilities = new SatelliteCapabilities();
+        capabilities.supportedRadioTechnologies = SUPPORTED_RADIO_TECHNOLOGIES;
+        capabilities.isPointingRequired = POINTING_TO_SATELLITE_REQUIRED;
+        capabilities.maxBytesPerOutgoingDatagram = MAX_BYTES_PER_DATAGRAM;
+        runWithExecutor(() -> callback.accept(capabilities));
+    }
+
+    @Override
+    public void startSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+        logd("startSendingSatellitePointingInfo");
+        if (!verifySatelliteModemState(errorCallback)) {
+            return;
+        }
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void stopSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+        logd("stopSendingSatellitePointingInfo");
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("provisionSatelliteService");
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        updateSatelliteProvisionState(true);
+    }
+
+    @Override
+    public void deprovisionSatelliteService(@NonNull String token,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("deprovisionSatelliteService");
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        updateSatelliteProvisionState(false);
+    }
+
+    @Override
+    public void requestIsSatelliteProvisioned(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteProvisioned");
+        runWithExecutor(() -> callback.accept(mIsProvisioned));
+    }
+
+    @Override
+    public void pollPendingSatelliteDatagrams(@NonNull IIntegerConsumer errorCallback) {
+        logd("pollPendingSatelliteDatagrams");
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("sendSatelliteDatagram");
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void requestSatelliteModemState(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IIntegerConsumer callback) {
+        logd("requestSatelliteModemState");
+        runWithExecutor(() -> callback.accept(mModemState));
+    }
+
+    @Override
+    public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+            @NonNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteCommunicationAllowedForCurrentLocation");
+        if (mIsCommunicationAllowedInLocation) {
+            runWithExecutor(() -> callback.accept(true));
+        } else {
+            runWithExecutor(() -> callback.accept(false));
+        }
+    }
+
+    @Override
+    public void requestTimeForNextSatelliteVisibility(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IIntegerConsumer callback) {
+        logd("requestTimeForNextSatelliteVisibility");
+        runWithExecutor(() -> callback.accept(SATELLITE_ALWAYS_VISIBLE));
+    }
+
+    /**
+     * Helper method to verify that the satellite modem is properly configured to receive requests.
+     *
+     * @param errorCallback The callback to notify of any errors preventing satellite requests.
+     * @return {@code true} if the satellite modem is configured to receive requests and
+     *         {@code false} if it is not.
+     */
+    private boolean verifySatelliteModemState(@NonNull IIntegerConsumer errorCallback) {
+        if (!mIsSupported) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.REQUEST_NOT_SUPPORTED));
+            return false;
+        }
+        if (!mIsProvisioned) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.SERVICE_NOT_PROVISIONED));
+            return false;
+        }
+        if (!mIsEnabled) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.INVALID_MODEM_STATE));
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Update the satellite modem state and notify listeners if it changed.
+     *
+     * @param modemState The {@link SatelliteModemState} to update.
+     */
+    private void updateSatelliteModemState(int modemState) {
+        if (modemState == mModemState) {
+            return;
+        }
+        logd("updateSatelliteModemState: mListeners.size=" + mListeners.size());
+        mListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatelliteModemStateChanged(modemState)));
+        mModemState = modemState;
+    }
+
+    /**
+     * Update the satellite provision state and notify listeners if it changed.
+     *
+     * @param isProvisioned {@code true} if the satellite is currently provisioned and
+     *                      {@code false} if it is not.
+     */
+    private void updateSatelliteProvisionState(boolean isProvisioned) {
+        if (isProvisioned == mIsProvisioned) {
+            return;
+        }
+        logd("updateSatelliteProvisionState: mListeners.size=" + mListeners.size());
+        mIsProvisioned = isProvisioned;
+        mListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatelliteProvisionStateChanged(mIsProvisioned)));
+    }
+
+    /**
+     * Execute the given runnable using the executor that this service was created with.
+     *
+     * @param r A runnable that can throw an exception.
+     */
+    private void runWithExecutor(@NonNull FunctionalUtils.ThrowingRunnable r) {
+        mExecutor.execute(() -> Binder.withCleanCallingIdentity(r));
+    }
+
+    /**
+     * Log the message to the radio buffer with {@code DEBUG} priority.
+     *
+     * @param log The message to log.
+     */
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+}
diff --git a/host/commands/assemble_cvd/bootconfig_args.cpp b/host/commands/assemble_cvd/bootconfig_args.cpp
index 4e24f74..e8c99c7 100644
--- a/host/commands/assemble_cvd/bootconfig_args.cpp
+++ b/host/commands/assemble_cvd/bootconfig_args.cpp
@@ -121,16 +121,6 @@
         std::to_string(instance.config_server_port());
   }
 
-  if (instance.enable_vehicle_hal_grpc_server() &&
-      instance.vehicle_hal_server_port() &&
-      FileExists(VehicleHalGrpcServerBinary())) {
-    constexpr int vehicle_hal_server_cid = 2;
-    bootconfig_args["androidboot.vendor.vehiclehal.server.cid"] =
-        std::to_string(vehicle_hal_server_cid);
-    bootconfig_args["androidboot.vendor.vehiclehal.server.port"] =
-        std::to_string(instance.vehicle_hal_server_port());
-  }
-
   if (instance.audiocontrol_server_port()) {
     bootconfig_args["androidboot.vendor.audiocontrol.server.cid"] =
         std::to_string(instance.vsock_guest_cid());
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 2c43e13..5dac23d 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -299,10 +299,6 @@
 DEFINE_vec(restart_subprocesses,
            fmt::format("{}", CF_DEFAULTS_RESTART_SUBPROCESSES),
            "Restart any crashed host process");
-DEFINE_vec(enable_vehicle_hal_grpc_server,
-           fmt::format("{}", CF_DEFAULTS_ENABLE_VEHICLE_HAL_GRPC_SERVER),
-           "Enables the vehicle HAL "
-           "emulation gRPC server on the host");
 DEFINE_vec(bootloader, CF_DEFAULTS_BOOTLOADER, "Bootloader binary path");
 DEFINE_vec(boot_slot, CF_DEFAULTS_BOOT_SLOT,
               "Force booting into the given slot. If empty, "
@@ -1051,8 +1047,6 @@
       modem_simulator_sim_type));
   std::vector<bool> console_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(console));
   std::vector<bool> enable_audio_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(enable_audio));
-  std::vector<bool> enable_vehicle_hal_grpc_server_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(
-      enable_vehicle_hal_grpc_server));
   std::vector<bool> start_gnss_proxy_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(
       start_gnss_proxy));
   std::vector<bool> enable_bootanimation_vec =
@@ -1257,8 +1251,6 @@
       guest_configs[instance_index].hctr2_supported ? "hctr2" : "cts");
     instance.set_use_allocd(use_allocd_vec[instance_index]);
     instance.set_enable_audio(enable_audio_vec[instance_index]);
-    instance.set_enable_vehicle_hal_grpc_server(
-      enable_vehicle_hal_grpc_server_vec[instance_index]);
     instance.set_enable_gnss_grpc_proxy(start_gnss_proxy_vec[instance_index]);
     instance.set_enable_bootanimation(enable_bootanimation_vec[instance_index]);
     instance.set_record_screen(record_screen_vec[instance_index]);
@@ -1413,7 +1405,6 @@
     instance.set_ethernet_ipv6(Ipv6ToString(ethernet_ipv6));
 
     instance.set_tombstone_receiver_port(calc_vsock_port(6600));
-    instance.set_vehicle_hal_server_port(9300 + num - 1);
     instance.set_audiocontrol_server_port(9410);  /* OK to use the same port number across instances */
     instance.set_config_server_port(calc_vsock_port(6800));
     instance.set_lights_server_port(calc_vsock_port(6900));
diff --git a/host/commands/assemble_cvd/flags_defaults.h b/host/commands/assemble_cvd/flags_defaults.h
index 2817c97..eff1c4d 100644
--- a/host/commands/assemble_cvd/flags_defaults.h
+++ b/host/commands/assemble_cvd/flags_defaults.h
@@ -203,9 +203,6 @@
 #define CF_DEFAULTS_RUN_ADB_CONNECTOR true
 #define CF_DEFAULTS_ADB_MODE "vsock_half_tunnel"
 
-// Vehicle default parameters
-#define CF_DEFAULTS_ENABLE_VEHICLE_HAL_GRPC_SERVER true
-
 // Location default parameters
 #define CF_DEFAULTS_START_GNSS_PROXY true
 #define CF_DEFAULTS_FIXED_LOCATION_FILE_PATH CF_DEFAULTS_DYNAMIC_STRING
diff --git a/host/commands/cvd/parser/doc/vehicle.dot b/host/commands/cvd/parser/doc/vehicle.dot
deleted file mode 100644
index 6931be5..0000000
--- a/host/commands/cvd/parser/doc/vehicle.dot
+++ /dev/null
@@ -1,5 +0,0 @@
-graph {
-  rankdir=LR
-
-  vehicle--enable_vehicle_hal_grpc_server
-}
\ No newline at end of file
diff --git a/host/commands/cvd/parser/doc/vehicle.png b/host/commands/cvd/parser/doc/vehicle.png
deleted file mode 100644
index fe74503..0000000
--- a/host/commands/cvd/parser/doc/vehicle.png
+++ /dev/null
Binary files differ
diff --git a/host/commands/cvd/parser/doc/vehicle.svg b/host/commands/cvd/parser/doc/vehicle.svg
deleted file mode 100644
index ee45abc..0000000
--- a/host/commands/cvd/parser/doc/vehicle.svg
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: %3 Pages: 1 -->
-<svg width="365pt" height="44pt"
- viewBox="0.00 0.00 365.07 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
-<title>%3</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-40 361.07,-40 361.07,4 -4,4"/>
-<!-- vehicle -->
-<g id="node1" class="node">
-<title>vehicle</title>
-<ellipse fill="none" stroke="black" cx="36.4" cy="-18" rx="36.29" ry="18"/>
-<text text-anchor="middle" x="36.4" y="-14.3" font-family="Times,serif" font-size="14.00">vehicle</text>
-</g>
-<!-- enable_vehicle_hal_grpc_server -->
-<g id="node2" class="node">
-<title>enable_vehicle_hal_grpc_server</title>
-<ellipse fill="none" stroke="black" cx="232.93" cy="-18" rx="124.28" ry="18"/>
-<text text-anchor="middle" x="232.93" y="-14.3" font-family="Times,serif" font-size="14.00">enable_vehicle_hal_grpc_server</text>
-</g>
-<!-- vehicle&#45;&#45;enable_vehicle_hal_grpc_server -->
-<g id="edge1" class="edge">
-<title>vehicle&#45;&#45;enable_vehicle_hal_grpc_server</title>
-<path fill="none" stroke="black" d="M73.08,-18C83.61,-18 95.77,-18 108.59,-18"/>
-</g>
-</g>
-</svg>
diff --git a/host/commands/run_cvd/Android.bp b/host/commands/run_cvd/Android.bp
index 3f8b4f6..487bca4 100644
--- a/host/commands/run_cvd/Android.bp
+++ b/host/commands/run_cvd/Android.bp
@@ -39,7 +39,6 @@
         "launch/pica.cpp",
         "launch/secure_env.cpp",
         "launch/streamer.cpp",
-        "launch/vehicle_hal_server.cpp",
         "launch/netsim_server.cpp",
         "launch/mcu.cpp",
         "main.cc",
diff --git a/host/commands/run_cvd/doc/linkage.dot b/host/commands/run_cvd/doc/linkage.dot
index 8a6ca8c..d556e10 100644
--- a/host/commands/run_cvd/doc/linkage.dot
+++ b/host/commands/run_cvd/doc/linkage.dot
@@ -20,7 +20,6 @@
   secure_env
   stop_cvd
   tombstone_receiver
-  vehicle_hal_server [label = "android.hardware.automotive.vehicle@2.0-virtualization-grpc-server"]
 
   subgraph cluster_adb_group {
     label = "ADB"
@@ -101,7 +100,6 @@
   run_cvd -> secure_env
   run_cvd -> socket_vsock_proxy [style = "dashed"]
   run_cvd -> tombstone_receiver
-  run_cvd -> vehicle_hal_server [style = "dashed"]
   run_cvd -> vmm
   run_cvd -> webrtc [style = "dashed"]
   run_cvd -> wmediumd
diff --git a/host/commands/run_cvd/doc/linkage.svg b/host/commands/run_cvd/doc/linkage.svg
index d061a92..11c8c58 100644
--- a/host/commands/run_cvd/doc/linkage.svg
+++ b/host/commands/run_cvd/doc/linkage.svg
@@ -280,18 +280,6 @@
 <path fill="none" stroke="black" d="M490.32,-869.8C498.24,-903.26 520.25,-974.8 569.08,-1007.87 620.09,-1042.41 690.55,-1047.4 744.28,-1044.74"/>
 <polygon fill="black" stroke="black" points="744.68,-1048.22 754.46,-1044.14 744.27,-1041.24 744.68,-1048.22"/>
 </g>
-<!-- vehicle_hal_server -->
-<g id="node20" class="node">
-<title>vehicle_hal_server</title>
-<ellipse fill="none" stroke="black" cx="823.86" cy="-980.87" rx="254.55" ry="18"/>
-<text text-anchor="middle" x="823.86" y="-977.17" font-family="Times,serif" font-size="14.00">android.hardware.automotive.vehicle@2.0&#45;virtualization&#45;grpc&#45;server</text>
-</g>
-<!-- run_cvd&#45;&gt;vehicle_hal_server -->
-<g id="edge34" class="edge">
-<title>run_cvd&#45;&gt;vehicle_hal_server</title>
-<path fill="none" stroke="black" stroke-dasharray="5,2" d="M494.53,-869.62C506.62,-894.44 532.25,-938.73 569.08,-958.87 575.68,-962.48 582.53,-965.71 589.56,-968.58"/>
-<polygon fill="black" stroke="black" points="588.66,-971.99 599.25,-972.3 591.16,-965.45 588.66,-971.99"/>
-</g>
 <!-- adb_connector -->
 <g id="node21" class="node">
 <title>adb_connector</title>
diff --git a/host/commands/run_cvd/launch/launch.h b/host/commands/run_cvd/launch/launch.h
index 553950a..942ed9c 100644
--- a/host/commands/run_cvd/launch/launch.h
+++ b/host/commands/run_cvd/launch/launch.h
@@ -109,9 +109,6 @@
 fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>
 TombstoneReceiverComponent();
 
-fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>
-VehicleHalServerComponent();
-
 fruit::Component<fruit::Required<const CuttlefishConfig,
                                  const CuttlefishConfig::EnvironmentSpecific,
                                  LogTeeCreator, GrpcSocketCreator>>
diff --git a/host/commands/run_cvd/launch/vehicle_hal_server.cpp b/host/commands/run_cvd/launch/vehicle_hal_server.cpp
deleted file mode 100644
index bf84679..0000000
--- a/host/commands/run_cvd/launch/vehicle_hal_server.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "host/commands/run_cvd/launch/launch.h"
-
-#include <string>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include <fruit/fruit.h>
-
-#include "common/libs/utils/files.h"
-#include "common/libs/utils/result.h"
-#include "host/libs/config/command_source.h"
-#include "host/libs/config/known_paths.h"
-
-namespace cuttlefish {
-namespace {
-
-class VehicleHalServer : public CommandSource {
- public:
-  INJECT(VehicleHalServer(const CuttlefishConfig::InstanceSpecific& instance))
-      : instance_(instance) {}
-
-  // CommandSource
-  Result<std::vector<MonitorCommand>> Commands() override {
-    Command grpc_server(VehicleHalGrpcServerBinary());
-
-    const unsigned vhal_server_cid = 2;
-    const unsigned vhal_server_port = instance_.vehicle_hal_server_port();
-    const std::string vhal_server_power_state_file =
-        AbsolutePath(instance_.PerInstancePath("power_state"));
-    const std::string vhal_server_power_state_socket =
-        AbsolutePath(instance_.PerInstanceUdsPath("power_state_socket"));
-
-    grpc_server.AddParameter("--server_cid=", vhal_server_cid);
-    grpc_server.AddParameter("--server_port=", vhal_server_port);
-    grpc_server.AddParameter("--power_state_file=",
-                             vhal_server_power_state_file);
-    grpc_server.AddParameter("--power_state_socket=",
-                             vhal_server_power_state_socket);
-    std::vector<MonitorCommand> commands;
-    commands.emplace_back(std::move(grpc_server));
-    return commands;
-  }
-
-  // SetupFeature
-  std::string Name() const override { return "VehicleHalServer"; }
-  bool Enabled() const override {
-    return instance_.enable_vehicle_hal_grpc_server() &&
-           FileExists(VehicleHalGrpcServerBinary());
-  }
-
- private:
-  std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
-  Result<void> ResultSetup() override { return {}; }
-
- private:
-  const CuttlefishConfig::InstanceSpecific& instance_;
-};
-
-}  // namespace
-
-fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>
-VehicleHalServerComponent() {
-  return fruit::createComponent()
-      .addMultibinding<CommandSource, VehicleHalServer>()
-      .addMultibinding<SetupFeature, VehicleHalServer>();
-}
-
-}  // namespace cuttlefish
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index 9a76584..cb4285b 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -159,7 +159,6 @@
       .install(CasimirComponent)
       .install(NetsimServerComponent)
       .install(SecureEnvComponent)
-      .install(VehicleHalServerComponent)
       .install(serverLoopComponent)
       .install(validationComponent)
       .install(vm_manager::VmManagerComponent);
diff --git a/host/commands/start/main.cc b/host/commands/start/main.cc
index 29dcc76..6d45c3f 100644
--- a/host/commands/start/main.cc
+++ b/host/commands/start/main.cc
@@ -249,7 +249,6 @@
                                               "enable_gpu_udmabuf",
                                               "enable_gpu_vhost_user",
                                               "enable_audio",
-                                              "enable_vehicle_hal_grpc_server",
                                               "start_gnss_proxy",
                                               "enable_bootanimation",
                                               "record_screen",
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 6e3736a..0c688c2 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -316,8 +316,6 @@
     int tombstone_receiver_port() const;
     // Port number to connect to the config server on the host
     int config_server_port() const;
-    // Port number to connect to the vehicle HAL server on the host
-    int vehicle_hal_server_port() const;
     // Port number to connect to the audiocontrol server on the guest
     int audiocontrol_server_port() const;
     // Port number to connect to the adb server on the host
@@ -551,7 +549,6 @@
     bool pause_in_bootloader() const;
     bool run_as_daemon() const;
     bool enable_audio() const;
-    bool enable_vehicle_hal_grpc_server() const;
     bool enable_gnss_grpc_proxy() const;
     bool enable_bootanimation() const;
     bool record_screen() const;
@@ -669,7 +666,6 @@
     void set_keyboard_server_port(int config_server_port);
     void set_gatekeeper_vsock_port(int gatekeeper_vsock_port);
     void set_keymaster_vsock_port(int keymaster_vsock_port);
-    void set_vehicle_hal_server_port(int vehicle_server_port);
     void set_audiocontrol_server_port(int audiocontrol_server_port);
     void set_lights_server_port(int lights_server_port);
     void set_adb_host_port(int adb_host_port);
@@ -738,7 +734,6 @@
     void set_pause_in_bootloader(bool pause_in_bootloader);
     void set_run_as_daemon(bool run_as_daemon);
     void set_enable_audio(bool enable);
-    void set_enable_vehicle_hal_grpc_server(bool enable_vhal_server);
     void set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy);
     void set_enable_bootanimation(const bool enable_bootanimation);
     void set_record_screen(bool record_screen);
diff --git a/host/libs/config/cuttlefish_config_instance.cpp b/host/libs/config/cuttlefish_config_instance.cpp
index ba7efd0..100a848 100644
--- a/host/libs/config/cuttlefish_config_instance.cpp
+++ b/host/libs/config/cuttlefish_config_instance.cpp
@@ -755,14 +755,6 @@
   return (*Dictionary())[kEnableAudio].asBool();
 }
 
-static constexpr char kEnableVehicleHalServer[] = "enable_vehicle_hal_server";
-void CuttlefishConfig::MutableInstanceSpecific::set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server) {
-  (*Dictionary())[kEnableVehicleHalServer] = enable_vehicle_hal_grpc_server;
-}
-bool CuttlefishConfig::InstanceSpecific::enable_vehicle_hal_grpc_server() const {
-  return (*Dictionary())[kEnableVehicleHalServer].asBool();
-}
-
 static constexpr char kEnableGnssGrpcProxy[] = "enable_gnss_grpc_proxy";
 void CuttlefishConfig::MutableInstanceSpecific::set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy) {
   (*Dictionary())[kEnableGnssGrpcProxy] = enable_gnss_grpc_proxy;
@@ -1384,14 +1376,6 @@
   (*Dictionary())[kTombstoneReceiverPort] = tombstone_receiver_port;
 }
 
-static constexpr char kVehicleHalServerPort[] = "vehicle_hal_server_port";
-int CuttlefishConfig::InstanceSpecific::vehicle_hal_server_port() const {
-  return (*Dictionary())[kVehicleHalServerPort].asInt();
-}
-void CuttlefishConfig::MutableInstanceSpecific::set_vehicle_hal_server_port(int vehicle_hal_server_port) {
-  (*Dictionary())[kVehicleHalServerPort] = vehicle_hal_server_port;
-}
-
 static constexpr char kAudioControlServerPort[] = "audiocontrol_server_port";
 int CuttlefishConfig::InstanceSpecific::audiocontrol_server_port() const {
   return (*Dictionary())[kAudioControlServerPort].asInt();
diff --git a/host/libs/config/known_paths.cpp b/host/libs/config/known_paths.cpp
index 99c56a2..6c5dd10 100644
--- a/host/libs/config/known_paths.cpp
+++ b/host/libs/config/known_paths.cpp
@@ -88,11 +88,6 @@
   return HostBinaryPath("tombstone_receiver");
 }
 
-std::string VehicleHalGrpcServerBinary() {
-  return HostBinaryPath(
-      "android.hardware.automotive.vehicle@2.0-virtualization-grpc-server");
-}
-
 std::string WebRtcBinary() {
   return HostBinaryPath("webRTC");
 }
diff --git a/host/libs/config/known_paths.h b/host/libs/config/known_paths.h
index 4a6f441..d2ec352 100644
--- a/host/libs/config/known_paths.h
+++ b/host/libs/config/known_paths.h
@@ -40,7 +40,6 @@
 std::string StopCvdBinary();
 std::string TcpConnectorBinary();
 std::string TombstoneReceiverBinary();
-std::string VehicleHalGrpcServerBinary();
 std::string WebRtcBinary();
 std::string WebRtcSigServerBinary();
 std::string WebRtcSigServerProxyBinary();
diff --git a/shared/auto/audio_policy_configuration.xml b/shared/auto/audio_policy_configuration.xml
index f1ac5ad..dedc831 100644
--- a/shared/auto/audio_policy_configuration.xml
+++ b/shared/auto/audio_policy_configuration.xml
@@ -29,6 +29,7 @@
         <attachedDevices>
             <item>Speaker</item>
             <item>Built-In Mic</item>
+            <item>FM Tuner</item>
         </attachedDevices>
         <defaultOutputDevice>Speaker</defaultOutputDevice>
         <mixPorts>
@@ -40,6 +41,10 @@
                 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                     samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
             </mixPort>
+            <mixPort name="mixport_tuner0" role="sink">
+                <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                    samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+            </mixPort>
         </mixPorts>
         <devicePorts>
             <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_BUS"
@@ -54,12 +59,24 @@
 
             <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
             </devicePort>
+
+            <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"
+                address="tuner0">
+                <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                    samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                <gains>
+                    <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
+                        minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                </gains>
+            </devicePort>
         </devicePorts>
         <routes>
             <route type="mix" sink="Speaker"
                 sources="primary output"/>
             <route type="mix" sink="primary input"
                 sources="Built-In Mic"/>
+            <route type="mix" sink="mixport_tuner0"
+                sources="FM Tuner"/>
         </routes>
       </module>
 
diff --git a/shared/auto/car_audio_configuration.xml b/shared/auto/car_audio_configuration.xml
index 53ca217..482726e 100644
--- a/shared/auto/car_audio_configuration.xml
+++ b/shared/auto/car_audio_configuration.xml
@@ -21,27 +21,31 @@
     - Volume groups
   in the car environment.
 -->
-<carAudioConfiguration version="2">
+<carAudioConfiguration version="3">
     <zones>
-        <zone name="primary zone" isPrimary="true">
-            <volumeGroups>
-                <group>
-                    <device address="Speaker">
-                        <context context="music"/>
-                        <context context="navigation"/>
-                        <context context="voice_command"/>
-                        <context context="call_ring"/>
-                        <context context="call"/>
-                        <context context="alarm"/>
-                        <context context="notification"/>
-                        <context context="system_sound"/>
-                        <context context="emergency"/>
-                        <context context="safety"/>
-                        <context context="vehicle_status"/>
-                        <context context="announcement"/>
-                    </device>
-                </group>
-            </volumeGroups>
+        <zone name="Primary zone" isPrimary="true" occupantZoneId="0">
+            <zoneConfigs>
+                <zoneConfig name="Config 0" isDefault="true">
+                    <volumeGroups>
+                        <group>
+                            <device address="Speaker">
+                                <context context="music"/>
+                                <context context="navigation"/>
+                                <context context="voice_command"/>
+                                <context context="call_ring"/>
+                                <context context="call"/>
+                                <context context="alarm"/>
+                                <context context="notification"/>
+                                <context context="system_sound"/>
+                                <context context="emergency"/>
+                                <context context="safety"/>
+                                <context context="vehicle_status"/>
+                                <context context="announcement"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                </zoneConfig>
+            </zoneConfigs>
         </zone>
     </zones>
 </carAudioConfiguration>
diff --git a/shared/auto/device_vendor.mk b/shared/auto/device_vendor.mk
index 4cc46dc..97986b3 100644
--- a/shared/auto/device_vendor.mk
+++ b/shared/auto/device_vendor.mk
@@ -14,7 +14,6 @@
 # limitations under the License.
 #
 
-DEVICE_MANIFEST_FILE += device/google/cuttlefish/shared/auto/manifest.xml
 PRODUCT_MANIFEST_FILES += device/google/cuttlefish/shared/config/product_manifest.xml
 SYSTEM_EXT_MANIFEST_FILES += device/google/cuttlefish/shared/config/system_ext_manifest.xml
 
@@ -81,7 +80,10 @@
 PRODUCT_PACKAGES += android.hardware.automotive.remoteaccess@V1-default-service
 
 # Broadcast Radio
-PRODUCT_PACKAGES += android.hardware.broadcastradio@2.0-service
+PRODUCT_PACKAGES += android.hardware.broadcastradio-service.default
+
+# IVN HAL
+PRODUCT_PACKAGES += android.hardware.automotive.ivn@V1-default-service
 
 # AudioControl HAL
 ifeq ($(LOCAL_AUDIOCONTROL_HAL_PRODUCT_PACKAGE),)
@@ -91,7 +93,7 @@
 PRODUCT_PACKAGES += $(LOCAL_AUDIOCONTROL_HAL_PRODUCT_PACKAGE)
 
 # CAN bus HAL
-PRODUCT_PACKAGES += android.hardware.automotive.can@1.0-service
+PRODUCT_PACKAGES += android.hardware.automotive.can-service
 PRODUCT_PACKAGES_DEBUG += canhalctrl \
     canhaldump \
     canhalsend
@@ -116,8 +118,10 @@
 
 ifeq ($(ENABLE_MOCK_EVSHAL), true)
 CUSTOMIZE_EVS_SERVICE_PARAMETER := true
-PRODUCT_PACKAGES += android.hardware.automotive.evs@1.1-service \
-    android.frameworks.automotive.display@1.0-service
+PRODUCT_PACKAGES += \
+    android.hardware.automotive.evs-aidl-default-service \
+    cardisplayproxyd
+
 PRODUCT_COPY_FILES += \
     device/google/cuttlefish/shared/auto/evs/init.evs.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.evs.rc
 BOARD_SEPOLICY_DIRS += device/google/cuttlefish/shared/auto/sepolicy/evs
@@ -126,7 +130,7 @@
 ifeq ($(ENABLE_SAMPLE_EVS_APP), true)
 PRODUCT_PACKAGES += evs_app
 PRODUCT_COPY_FILES += \
-    device/google/cuttlefish/shared/auto/evs/evs_app_config.json:$(TARGET_COPY_OUT_SYSTEM)/etc/automotive/evs/config_override.json
+    device/google/cuttlefish/shared/auto/evs/evs_app_config.json:$(TARGET_COPY_OUT_VENDOR)/etc/automotive/evs/config_override.json
 include packages/services/Car/cpp/evs/apps/sepolicy/evsapp.mk
 endif
 
diff --git a/shared/auto/evs/init.evs.rc b/shared/auto/evs/init.evs.rc
index f7dace5..d0b997a 100644
--- a/shared/auto/evs/init.evs.rc
+++ b/shared/auto/evs/init.evs.rc
@@ -1,6 +1,6 @@
 on late-init
-    start automotive_display
-    start vendor.evs-hal-mock
+    start cardisplayproxyd
+    start vendor.evs-hal-cf
     start evs_manager_cf
 
 service evs_manager_cf /system/bin/evsmanagerd --target hw/0
@@ -9,3 +9,12 @@
     user automotive_evs
     group automotive_evs system
     disabled # will not automatically start with its class; must be explicitly started.
+
+service vendor.evs-hal-cf /vendor/bin/hw/android.hardware.automotive.evs-aidl-default-service
+    class hal
+    priority -20
+    user graphics
+    group automotive_evs camera
+    onrestart restart cardisplayproxyd
+    onrestart restart evs_manager_cf
+    disabled # will not automatically start with its class; must be explicitly started.
diff --git a/shared/auto/manifest.xml b/shared/auto/manifest.xml
deleted file mode 100644
index e1691a1..0000000
--- a/shared/auto/manifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-** limitations under the License.
-*/
--->
-<!-- Android Auto Embedded specific HALs-->
-<manifest version="1.0" type="device">
-    <hal format="hidl">
-        <name>android.hardware.automotive.can</name>
-        <transport>hwbinder</transport>
-        <fqname>@1.0::ICanBus/test</fqname>
-    </hal>
-</manifest>
diff --git a/shared/auto/preinstalled-packages-product-car-cuttlefish.xml b/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
index 0aca16b..90ba3b6 100644
--- a/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
+++ b/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
@@ -30,10 +30,6 @@
         <install-in user-type="FULL" />
         <install-in user-type="SYSTEM" />
     </install-in-user-type>
-    <install-in-user-type package="com.android.car.hvac">
-        <install-in user-type="FULL" />
-        <install-in user-type="SYSTEM" />
-    </install-in-user-type>
     <install-in-user-type package="com.android.phone">
         <install-in user-type="FULL" />
         <install-in user-type="SYSTEM" />
@@ -46,11 +42,6 @@
         <install-in user-type="FULL" />
         <install-in user-type="SYSTEM" />
     </install-in-user-type>
-    <!-- Android remote display which need to work for all users-->
-    <install-in-user-type package="com.android.car.acast.source">
-        <install-in user-type="FULL" />
-        <install-in user-type="SYSTEM" />
-    </install-in-user-type>
     <!-- This application is needed in ModuleInfoProvider -->
     <install-in-user-type package="com.android.modulemetadata">
         <install-in user-type="FULL" />
diff --git a/shared/auto/rro_overlay/CarServiceOverlay/res/values/config.xml b/shared/auto/rro_overlay/CarServiceOverlay/res/values/config.xml
index 6cfd2cc..e889df3 100644
--- a/shared/auto/rro_overlay/CarServiceOverlay/res/values/config.xml
+++ b/shared/auto/rro_overlay/CarServiceOverlay/res/values/config.xml
@@ -61,22 +61,27 @@
         occupant.
 
         Some examples are:
-        <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
-        <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
-        <item>displayPort=2,displayType=MAIN,occupantZoneId=1</item>
-        <item>displayPort=3,displayType=MAIN,occupantZoneId=2</item>
-        <item>displayPort=4,displayType=MAIN,occupantZoneId=3</item>
+        <item>displayPort=0,displayType=MAIN,occupantZoneId=0,inputTypes=DPAD_KEYS|
+            NAVIGATE_KEYS|ROTARY_NAVIGATION</item>
+        <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0,
+            inputTypes=DPAD_KEYS</item>
+        <item>displayPort=2,displayType=MAIN,occupantZoneId=1,
+            inputTypes=NAVIGATE_KEYS</item>
+        <item>displayPort=3,displayType=MAIN,occupantZoneId=2,
+            inputTypes=NAVIGATE_KEYS</item>
+        <item>displayUniqueId=virtual:com.example:MainD,displayType=MAIN,occupantZoneId=3,
+            inputTypes=NAVIGATE_KEYS</item>
 
         displayPort: Unique port id for the display.
         displayType: Display type for the display. Use * part from
                        CarOccupantZoneManager.DISPLAY_TYPE_* like MAIN, INSTRUMENT_CLUSTER and
                        etc.
         occupantZoneId: occupantZoneId specified from config_occupant_zones.
-
+        inputTypes: supported input types for the corresponding display.
     -->
     <string-array translatable="false" name="config_occupant_display_mapping">
-        <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
-        <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
+        <item>displayPort=0,displayType=MAIN,occupantZoneId=0,inputTypes=TOUCH_SCREEN|DPAD_KEYS|NAVIGATE_KEYS|ROTARY_NAVIGATION</item>
+        <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0,inputTypes=DPAD_KEYS</item>
     </string-array>
 
     <!-- A name of a camera device that provides the rearview through EVS service -->
diff --git a/shared/auto_md/OWNERS b/shared/auto_md/OWNERS
new file mode 100644
index 0000000..d3a1f82
--- /dev/null
+++ b/shared/auto_md/OWNERS
@@ -0,0 +1,2 @@
+include device/google/cuttlefish:/shared/auto/OWNERS
+ycheo@google.com
diff --git a/shared/auto_md/android-info.txt b/shared/auto_md/android-info.txt
new file mode 100644
index 0000000..ac7c0e7
--- /dev/null
+++ b/shared/auto_md/android-info.txt
@@ -0,0 +1 @@
+config=auto_md
diff --git a/shared/auto_md/display_settings.xml b/shared/auto_md/display_settings.xml
new file mode 100644
index 0000000..1922d42
--- /dev/null
+++ b/shared/auto_md/display_settings.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<!--
+/*
+** Copyright 2022, 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.
+*/
+-->
+
+<display-settings>
+
+  <!-- Use physical port number instead of local id -->
+  <config identifier="1" />
+
+  <!-- Display settings for cluster -->
+  <display name="port:1"
+      forcedDensity="120"
+      dontMoveToTop="true"/>
+
+  <!-- Display settings for 1st passenger display / 2nd Home -->
+  <display name="port:2"
+      shouldShowSystemDecors="true"
+      shouldShowIme="true"
+      forcedDensity="120" />
+
+  <!-- Display settings for 2nd passenger display / 3rd Home -->
+  <display name="port:3"
+      shouldShowSystemDecors="true"
+      shouldShowIme="true"
+      forcedDensity="120" />
+
+</display-settings>
diff --git a/shared/auto_md/overlay/frameworks/base/core/res/res/values/config.xml b/shared/auto_md/overlay/frameworks/base/core/res/res/values/config.xml
new file mode 100644
index 0000000..2ffb57a
--- /dev/null
+++ b/shared/auto_md/overlay/frameworks/base/core/res/res/values/config.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2022, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Whether the system enables per-display focus. If the system has the input method for each
+         display, this value should be true. -->
+    <bool name="config_perDisplayFocusEnabled">true</bool>
+
+    <!--  Maximum number of supported users -->
+    <integer name="config_multiuserMaximumUsers">10</integer>
+
+    <!-- Maximum number of users we allow to be running at a time -->
+    <integer name="config_multiuserMaxRunningUsers">5</integer>
+
+    <!-- True if the device supports system decorations on secondary displays. -->
+    <bool name="config_supportsSystemDecorsOnSecondaryDisplays">true</bool>
+    <!-- This is the default launcher package with an activity to use on secondary displays that
+         support system decorations.
+         This launcher package must have an activity that supports multiple instances and has
+         corresponding launch mode set in AndroidManifest.
+         {@see android.view.Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS} -->
+    <string name="config_secondaryHomePackage" translatable="false">com.android.car.multidisplay</string>
+    <!-- Whether to only install system packages on a user if they're whitelisted for that user
+         type. These are flags and can be freely combined.
+         0  - disable whitelist (install all system packages; no logging)
+         1  - enforce (only install system packages if they are whitelisted)
+         2  - log (log non-whitelisted packages)
+         4  - any package not mentioned in the whitelist file is implicitly whitelisted on all users
+         8  - same as 4, but just for the SYSTEM user
+         16 - ignore OTAs (don't install system packages during OTAs)
+         Common scenarios:
+          - to enable feature (fully enforced) for a complete whitelist: 1
+          - to enable feature for an incomplete whitelist (so use implicit whitelist mode): 5
+          - to enable feature but implicitly whitelist for SYSTEM user to ease local development: 9
+          - to disable feature completely if it had never been enabled: 16
+          - to henceforth disable feature and try to undo its previous effects: 0
+        Note: This list must be kept current with PACKAGE_WHITELIST_MODE_PROP in
+        frameworks/base/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+        Package whitelist disabled for testing profile user as default whitelist does not
+        support PROFILE user. -->
+    <integer name="config_userTypePackageWhitelistMode">2</integer>
+
+    <!-- Whether the device allows users to start in background visible on displays.
+         Should be false for most devices, except automotive vehicle with passenger displays. -->
+    <bool name="config_multiuserVisibleBackgroundUsers">true</bool>
+
+    <!-- Enable multi-user IME sessions -->
+    <string translatable="false" name="config_deviceSpecificInputMethodManagerService">com.android.server.inputmethod.InputMethodManagerServiceProxy$Lifecycle</string>
+
+</resources>
diff --git a/shared/auto_mdnd/overlay/frameworks/base/core/res/res/values/config.xml b/shared/auto_mdnd/overlay/frameworks/base/core/res/res/values/config.xml
new file mode 100644
index 0000000..b23af7a
--- /dev/null
+++ b/shared/auto_mdnd/overlay/frameworks/base/core/res/res/values/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2023, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Whether the device allows users to start in background visible on the default display.
+         Should be false for most devices, except passenger-only automotive build (i.e., when
+         Android runs in a separate system in the back seat to manage the passenger displays) -->
+    <bool name="config_multiuserVisibleBackgroundUsersOnDefaultDisplay">true</bool>
+</resources>
diff --git a/shared/auto_portrait/OWNERS b/shared/auto_portrait/OWNERS
new file mode 100644
index 0000000..5bc897b
--- /dev/null
+++ b/shared/auto_portrait/OWNERS
@@ -0,0 +1,4 @@
+include device/google/cuttlefish:/shared/auto/OWNERS
+babakbo@google.com
+calhuang@google.com
+priyanksingh@google.com
diff --git a/shared/auto_portrait/android-info.txt b/shared/auto_portrait/android-info.txt
new file mode 100644
index 0000000..60b759e
--- /dev/null
+++ b/shared/auto_portrait/android-info.txt
@@ -0,0 +1 @@
+config=auto_portrait
diff --git a/shared/auto_portrait/display_settings.xml b/shared/auto_portrait/display_settings.xml
new file mode 100644
index 0000000..54a1508
--- /dev/null
+++ b/shared/auto_portrait/display_settings.xml
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<!--
+/*
+** Copyright 2023, 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.
+*/
+-->
+
+<display-settings>
+
+  <!-- Use physical port number instead of local id -->
+  <config identifier="1" />
+
+</display-settings>
diff --git a/shared/camera/device_vendor.mk b/shared/camera/device_vendor.mk
index ce83efe..854d13b 100644
--- a/shared/camera/device_vendor.mk
+++ b/shared/camera/device_vendor.mk
@@ -29,6 +29,13 @@
 PRODUCT_SOONG_NAMESPACES += hardware/google/camera
 PRODUCT_SOONG_NAMESPACES += hardware/google/camera/devices/EmulatedCamera
 
+# TODO(b/257379485): 3A is incrementally enabling cuttlefish build for native
+# code coverage support, temporary require separate namespace for folders that
+# can be built successfully.
+PRODUCT_SOONG_NAMESPACES += vendor/google/camera/google_3a/libs_v4/g3ABase
+PRODUCT_SOONG_NAMESPACES += vendor/google/camera/google_3a/libs_v4/gAF
+PRODUCT_SOONG_NAMESPACES += vendor/google/camera/google_3a/libs_v4/gHAWB/native_coverage
+
 PRODUCT_COPY_FILES += \
     frameworks/native/data/etc/android.hardware.camera.concurrent.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.concurrent.xml \
     frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.flash-autofocus.xml \
diff --git a/shared/config/Android.bp b/shared/config/Android.bp
index a3a35a7..71f8d71 100644
--- a/shared/config/Android.bp
+++ b/shared/config/Android.bp
@@ -37,6 +37,18 @@
 }
 
 prebuilt_etc_host {
+    name: "cvd_config_auto_md.json",
+    src: "config_auto_md.json",
+    sub_dir: "cvd_config",
+}
+
+prebuilt_etc_host {
+    name: "cvd_config_auto_portrait.json",
+    src: "config_auto_portrait.json",
+    sub_dir: "cvd_config",
+}
+
+prebuilt_etc_host {
     name: "cvd_config_foldable.json",
     src: "config_foldable.json",
     sub_dir: "cvd_config",
diff --git a/shared/config/config_auto_md.json b/shared/config/config_auto_md.json
new file mode 100644
index 0000000..7eb22c3
--- /dev/null
+++ b/shared/config/config_auto_md.json
@@ -0,0 +1,7 @@
+{
+	"display0": "width=1080,height=600,dpi=120",
+	"display1": "width=400,height=600,dpi=120",
+	"display2": "width=800,height=600,dpi=120",
+	"display3": "width=800,height=600,dpi=120",
+	"memory_mb" : 4096
+}
diff --git a/shared/config/config_auto_portrait.json b/shared/config/config_auto_portrait.json
new file mode 100644
index 0000000..565f3dc
--- /dev/null
+++ b/shared/config/config_auto_portrait.json
@@ -0,0 +1,4 @@
+{
+	"display0": "width=1224,height=2175,dpi=140",
+	"memory_mb" : 4096
+}
diff --git a/shared/config/config_minidroid.json b/shared/config/config_minidroid.json
index eb84151..393c79f 100644
--- a/shared/config/config_minidroid.json
+++ b/shared/config/config_minidroid.json
@@ -6,7 +6,6 @@
 	"enable_host_bluetooth": false,
 	"netsim_bt": false,
 	"enable_modem_simulator": false,
-	"enable_vehicle_hal_grpc_server": false,
 	"gpu_mode" : "none",
 	"memory_mb" : 256,
 	"start_gnss_proxy": false,
diff --git a/shared/config/media_codecs_performance.xml b/shared/config/media_codecs_performance.xml
index a85067f..f3c5c48 100644
--- a/shared/config/media_codecs_performance.xml
+++ b/shared/config/media_codecs_performance.xml
@@ -113,6 +113,14 @@
             <!-- MANUALLY ADJUSTED -->
             <Limit name="measured-frame-rate-1280x720" range="23-23" />
         </MediaCodec>
+        <MediaCodec name="c2.android.av1.encoder" type="video/av01" update="true">
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-320x240" range="84-130" />
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-720x480" range="20-43" />
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-1280x720" range="8-21" />
+        </MediaCodec>
     </Encoders>
     <Decoders>
         <MediaCodec name="c2.android.avc.decoder" type="video/avc" update="true">
@@ -167,6 +175,16 @@
             <!-- 4 runs, min 65 max 88 gmean 77 -->
             <Limit name="measured-frame-rate-1920x1080" range="65-88" />
         </MediaCodec>
+        <MediaCodec name="c2.android.av1.decoder" type="video/av01" update="true">
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-320x180" range="156-362" />
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-640x360" range="63-162" />
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-1280x720" range="40-110" />
+            <!-- MANUALLY ADJUSTED -->
+            <Limit name="measured-frame-rate-1920x1080" range="17-54" />
+        </MediaCodec>
         <MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" update="true">
             <!-- 3 runs, min 1246 max 1390 gmean 1342 -->
             <Limit name="measured-frame-rate-176x144" range="1246-1390" />
diff --git a/shared/device.mk b/shared/device.mk
index 8b5fcb2..596ab0f 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -74,8 +74,7 @@
     persist.adb.tcp.port=5555 \
     ro.com.google.locationfeatures=1 \
     persist.sys.fuse.passthrough.enable=true \
-    persist.sys.fuse.bpf.enable=false \
-    remote_provisioning.tee.rkp_only=1 \
+    remote_provisioning.tee.rkp_only=1
 
 # Until we support adb keys on user builds, and fix logcat over serial,
 # spawn adbd by default without authorization for "adb logcat"
@@ -146,7 +145,7 @@
     suspend_blocker \
     metrics_helper \
 
-$(call soong_config_append,cvd,launch_configs,cvd_config_auto.json cvd_config_foldable.json cvd_config_go.json cvd_config_phone.json cvd_config_slim.json cvd_config_tablet.json cvd_config_tv.json cvd_config_wear.json)
+$(call soong_config_append,cvd,launch_configs,cvd_config_auto.json cvd_config_auto_portrait.json cvd_config_auto_md.json cvd_config_foldable.json cvd_config_go.json cvd_config_phone.json cvd_config_slim.json cvd_config_tablet.json cvd_config_tv.json cvd_config_wear.json)
 $(call soong_config_append,cvd,grub_config,grub.cfg)
 
 #
@@ -160,6 +159,18 @@
     wificond \
 
 #
+# Package for AOSP QNS
+#
+PRODUCT_PACKAGES += \
+    QualifiedNetworksService
+
+#
+# Package for AOSP GBA
+#
+PRODUCT_PACKAGES += \
+    GbaService
+
+#
 # Packages for testing
 #
 PRODUCT_PACKAGES += \
@@ -177,6 +188,11 @@
 
 endif
 
+#
+# Satellite vendor service for CF
+#
+PRODUCT_PACKAGES += CFSatelliteService
+
 # PRODUCT_AAPT_CONFIG and PRODUCT_AAPT_PREF_CONFIG are intentionally not set to
 # pick up every density resources.
 
@@ -231,6 +247,7 @@
     frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
     frameworks/av/services/audiopolicy/config/surround_sound_configuration_5_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/surround_sound_configuration_5_0.xml \
     device/google/cuttlefish/shared/config/task_profiles.json:$(TARGET_COPY_OUT_VENDOR)/etc/task_profiles.json \
+    frameworks/native/data/etc/android.software.credentials.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.credentials.xml \
 
 ifeq ($(LOCAL_PREFER_VENDOR_APEX),true)
 PRODUCT_PACKAGES += com.google.cf.input.config
@@ -265,8 +282,8 @@
 #
 # Weaver aidl HAL
 #
-PRODUCT_PACKAGES += \
-    android.hardware.weaver-service.example
+# TODO(b/262418065) Add a real weaver implementation
+
 
 #
 # Authsecret AIDL HAL
@@ -329,7 +346,7 @@
 # BiometricsFingerprint HAL (AIDL)
 #
 PRODUCT_PACKAGES += \
-    android.hardware.biometrics.fingerprint-service.example
+    com.android.hardware.biometrics.fingerprint.virtual
 
 #
 # Contexthub HAL
@@ -342,8 +359,9 @@
 # Drm HAL
 #
 PRODUCT_PACKAGES += \
-    android.hardware.drm@latest-service.clearkey \
-    android.hardware.drm@latest-service.widevine
+    android.hardware.drm@latest-service.clearkey
+
+-include vendor/widevine/libwvdrmengine/apex/device/device.mk
 
 #
 # Confirmation UI HAL
@@ -518,7 +536,7 @@
     setup_wifi \
     mac80211_create_radios \
     hostapd \
-    android.hardware.wifi@1.0-service \
+    android.hardware.wifi-service \
     init.wifi
 PRODUCT_COPY_FILES += \
     device/google/cuttlefish/shared/config/wpa_supplicant.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/wpa_supplicant.rc
@@ -579,6 +597,9 @@
 PRODUCT_SYSTEM_PROPERTIES += \
     ro.launcher.depth.widget=0
 
+# Start fingerprint virtual HAL process
+PRODUCT_VENDOR_PROPERTIES += ro.vendor.fingerprint_virtual_hal_start=true
+
 # Vendor Dlkm Locader
 PRODUCT_PACKAGES += \
    dlkm_loader
diff --git a/shared/graphics/device_vendor.mk b/shared/graphics/device_vendor.mk
index 169a430..b5f4102 100644
--- a/shared/graphics/device_vendor.mk
+++ b/shared/graphics/device_vendor.mk
@@ -54,8 +54,8 @@
 PRODUCT_COPY_FILES += \
     frameworks/native/data/etc/android.hardware.vulkan.level-0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.level.xml \
     frameworks/native/data/etc/android.hardware.vulkan.version-1_0_3.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml \
-    frameworks/native/data/etc/android.software.vulkan.deqp.level-2022-03-01.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.vulkan.deqp.level.xml \
-    frameworks/native/data/etc/android.software.opengles.deqp.level-2022-03-01.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.opengles.deqp.level.xml
+    frameworks/native/data/etc/android.software.vulkan.deqp.level-2023-03-01.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.vulkan.deqp.level.xml \
+    frameworks/native/data/etc/android.software.opengles.deqp.level-2023-03-01.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.opengles.deqp.level.xml
 endif
 endif
 
diff --git a/shared/overlays/foldable/core/res/values/config.xml b/shared/overlays/foldable/core/res/values/config.xml
index 8186c97..b101b36 100644
--- a/shared/overlays/foldable/core/res/values/config.xml
+++ b/shared/overlays/foldable/core/res/values/config.xml
@@ -26,11 +26,44 @@
       <item>2:3</item> <!-- OPENED : STATE_FLIPPED -->
       <item>3:1</item> <!-- REAR_DISPLAY: STATE_FLAT -->
   </string-array>
-  <!-- The device states (supplied by DeviceStateManager) that should be treated as folded by the
+
+  <!-- Map of DeviceState to rotation lock setting. Each entry must be in the format "key:value",
+     or "key:value:fallback_key" for example: "0:1" or "2:0:1". The keys are device states, and
+     the values are one of Settings.Secure.DeviceStateRotationLockSetting.
+     The fallback is a key to a device state that can be specified when the value is
+     Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED.
+ -->
+  <string-array name="config_perDeviceStateRotationLockDefaults" translatable="false">
+    <item>0:1</item> <!-- CLOSED -> LOCKED -->
+    <item>1:0:2</item> <!-- HALF_OPENED -> IGNORED and fallback to device state OPENED -->
+    <item>2:2</item> <!-- OPENED -> UNLOCKED -->
+    <item>3:0:0</item> <!-- REAR_DISPLAY -> IGNORED and fallback to device state CLOSED -->
+  </string-array>
+
+  <!-- The device states (supplied by DeviceStateManager) that should be treated as open by the
        display fold controller. -->
+  <integer-array name="config_openDeviceStates" translatable="false">
+    <item>2</item> <!-- OPEN -->
+  </integer-array>
+
+  <!-- The device states (supplied by DeviceStateManager) that should be treated as folded by the
+       display fold controller. This also controls the folded bit in CameraServiceProxy. -->
   <integer-array name="config_foldedDeviceStates" translatable="false">
     <item>0</item> <!-- CLOSED -->
   </integer-array>
+
+  <!-- The device states (supplied by DeviceStateManager) that should be treated as half folded by
+       the display fold controller. This also controls the folded bit in CameraServiceProxy. -->
+  <integer-array name="config_halfFoldedDeviceStates" translatable="false">
+    <item>1</item> <!-- HALF_OPENED -->
+  </integer-array>
+
+  <!-- The device states (supplied by DeviceStateManager) that should be treated as a rear display
+       state. Default is empty. -->
+  <integer-array name="config_rearDisplayDeviceStates" translatable="false">
+    <item>3</item> <!-- REAR_DISPLAY_STATE -->
+  </integer-array>
+
   <!-- Indicates whether to enable an animation when unfolding a device or not -->
   <bool name="config_unfoldTransitionEnabled">true</bool>
   <!-- Indicates whether to enable hinge angle sensor when using unfold animation -->
diff --git a/shared/phone/device_vendor.mk b/shared/phone/device_vendor.mk
index 78a452d..b9cadc5 100644
--- a/shared/phone/device_vendor.mk
+++ b/shared/phone/device_vendor.mk
@@ -51,6 +51,11 @@
     frameworks/native/data/etc/android.hardware.faketouch.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.faketouch.xml \
     frameworks/native/data/etc/android.hardware.fingerprint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.fingerprint.xml \
 
+    ifneq ($(TARGET_DISABLE_BIOMETRICS_FACE),true)
+        PRODUCT_COPY_FILES += \
+        frameworks/native/data/etc/android.hardware.biometrics.face.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.biometrics.face.xml \
+
+    endif
 endif
 
 DEVICE_PACKAGE_OVERLAYS += device/google/cuttlefish/shared/phone/overlay
diff --git a/shared/phone/overlays/CuttlefishTetheringOverlay/Android.bp b/shared/phone/overlays/CuttlefishTetheringOverlay/Android.bp
index 4b17443..3dcd123 100644
--- a/shared/phone/overlays/CuttlefishTetheringOverlay/Android.bp
+++ b/shared/phone/overlays/CuttlefishTetheringOverlay/Android.bp
@@ -23,3 +23,10 @@
     vendor: true,
     sdk_version: "current",
 }
+
+override_runtime_resource_overlay {
+    name: "CuttlefishTetheringOverlayGoogle",
+    base: "CuttlefishTetheringOverlay",
+    package_name: "com.google.android.networkstack.tethering.cuttlefishoverlay",
+    target_package_name: "com.google.android.networkstack.tethering",
+}
diff --git a/shared/phone/overlays/CuttlefishWifiOverlay/Android.bp b/shared/phone/overlays/CuttlefishWifiOverlay/Android.bp
index 4c05093..5330899 100644
--- a/shared/phone/overlays/CuttlefishWifiOverlay/Android.bp
+++ b/shared/phone/overlays/CuttlefishWifiOverlay/Android.bp
@@ -23,3 +23,10 @@
     vendor: true,
     sdk_version: "current",
 }
+
+override_runtime_resource_overlay {
+    name: "CuttlefishWifiOverlayGoogle",
+    base: "CuttlefishWifiOverlay",
+    package_name: "com.google.android.wifi.resources.cf",
+    target_package_name: "com.google.android.wifi.resources",
+}
diff --git a/shared/phone/overlays/CuttlefishWifiOverlay/res/values/config.xml b/shared/phone/overlays/CuttlefishWifiOverlay/res/values/config.xml
index f0d256f..c9a694e 100644
--- a/shared/phone/overlays/CuttlefishWifiOverlay/res/values/config.xml
+++ b/shared/phone/overlays/CuttlefishWifiOverlay/res/values/config.xml
@@ -19,6 +19,7 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- True if the firmware supports connected MAC randomization -->
     <bool name="config_wifi_connected_mac_randomization_supported">true</bool>
+    <bool name="config_wifiAllowNonPersistentMacRandomizationOnOpenSsids">true</bool>
 
     <!-- True if the firmware supports p2p MAC randomization -->
     <!-- TODO(b/237945863) Re-enable this flag when mac randomization for
diff --git a/shared/phone/overlays/core/res/values/config.xml b/shared/phone/overlays/core/res/values/config.xml
index e2f7c21..b7edba2 100644
--- a/shared/phone/overlays/core/res/values/config.xml
+++ b/shared/phone/overlays/core/res/values/config.xml
@@ -55,6 +55,8 @@
   <string name="config_mms_user_agent_profile_url" translatable="false">http://gsm.lge.com/html/gsm/Nexus5-M3.xml</string>
   <string name="config_wlan_data_service_package" translatable="false">com.android.ims</string>
   <string name="config_wlan_network_service_package" translatable="false">com.android.ims</string>
+  <string name="config_qualified_networks_service_package">com.android.qns</string>
+  <string name="config_gba_package">com.android.gbaservice</string>
 
   <!-- Enable Night display, which requires HWC 2.0. -->
   <bool name="config_nightDisplayAvailable">true</bool>
@@ -63,4 +65,7 @@
 
   <!-- Is the device capable of hot swapping an UICC Card -->
   <bool name="config_hotswapCapable">true</bool>
+
+  <!-- String indicating the package name of the vendor satellite service implementation -->
+  <string name="config_satellite_service_package" translatable="false">com.google.android.telephony.satellite</string>
 </resources>
diff --git a/shared/sepolicy/vendor/platform_app.te b/shared/sepolicy/vendor/platform_app.te
index bb4160d..703e39b 100644
--- a/shared/sepolicy/vendor/platform_app.te
+++ b/shared/sepolicy/vendor/platform_app.te
@@ -1,4 +1,9 @@
 gpu_access(platform_app)
 
 allow platform_app broadcastradio_service:service_manager find;
-allow platform_app hal_wlc_hwservice:hwservice_manager find;
\ No newline at end of file
+allow platform_app hal_wlc_hwservice:hwservice_manager find;
+
+# b/263830018
+# Ignore lookup for vendor.google.wireless_charger.IWirelessCharger/default
+# and vendor.google.google_battery.IGoogleBattery/default.
+dontaudit platform_app default_android_service:service_manager find;
diff --git a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
index 28412c7..2b57859 100644
--- a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
+++ b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
@@ -12,3 +12,4 @@
 get_prop(libcuttlefish_rild, vendor_modem_simulator_ports_prop)
 
 allow libcuttlefish_rild self:{ socket vsock_socket } { create_socket_perms_no_ioctl getattr };
+allow libcuttlefish_rild su:{ socket udp_socket } { create_socket_perms_no_ioctl getattr };
\ No newline at end of file
diff --git a/shared/telephony/device_vendor.mk b/shared/telephony/device_vendor.mk
index 1e4e7e0..bd78cc6 100644
--- a/shared/telephony/device_vendor.mk
+++ b/shared/telephony/device_vendor.mk
@@ -40,7 +40,8 @@
 endif
 PRODUCT_COPY_FILES += \
     frameworks/native/data/etc/android.hardware.telephony.gsm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.telephony.gsm.xml \
-    frameworks/native/data/etc/android.hardware.telephony.ims.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.telephony.ims.xml
+    frameworks/native/data/etc/android.hardware.telephony.ims.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.telephony.ims.xml \
+    frameworks/native/data/etc/android.hardware.telephony.satellite.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.telephony.satellite.xml
 endif # if not LOCAL_PREFER_VENDOR_APEX
 
 endif # if not TARGET_NO_TELEPHONY
diff --git a/shared/tv/device_vendor.mk b/shared/tv/device_vendor.mk
index e620fe4..0fe2071 100644
--- a/shared/tv/device_vendor.mk
+++ b/shared/tv/device_vendor.mk
@@ -62,8 +62,12 @@
 # Setup HDMI CEC as Playback Device
 PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=4
 
-# Tuner HAL
-PRODUCT_PACKAGES += android.hardware.tv.tuner-service.example
+# Tuner lazy HAL
+PRODUCT_PACKAGES += android.hardware.tv.tuner-service.example-lazy
+PRODUCT_VENDOR_PROPERTIES += ro.tuner.lazyhal=true
+
+# TV Input HAL
+PRODUCT_PACKAGES += android.hardware.tv.input-service.example
 
 # Sample Tuner Input for testing
 #PRODUCT_PACKAGES += LiveTv sampletunertvinput
diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp
index 3429fb1..7ea01f9 100644
--- a/tests/hal/hal_implementation_test.cpp
+++ b/tests/hal/hal_implementation_test.cpp
@@ -42,14 +42,10 @@
 using namespace android;
 
 // clang-format off
-static const std::set<std::string> kAutomotiveOnlyHidl = {
-    "android.frameworks.automotive.display@1.0",
-    "android.hardware.automotive.can@1.0",
-    "android.hardware.broadcastradio@2.0",
-};
-
 static const std::set<std::string> kKnownMissingHidl = {
+    "android.frameworks.automotive.display@1.0", // converted to AIDL, see b/170401743
     "android.frameworks.cameraservice.device@2.1",
+    "android.frameworks.cameraservice.service@2.2", // converted to AIDL, see b/205764761
     "android.frameworks.displayservice@1.0", // deprecated, see b/141930622
     "android.frameworks.schedulerservice@1.0", // deprecated, see b/37226359
     "android.frameworks.sensorservice@1.0", // deprecated, see b/205764765
@@ -68,6 +64,7 @@
     "android.hardware.authsecret@1.0", // converted to AIDL, see b/182976659
     "android.hardware.automotive.audiocontrol@1.0",
     "android.hardware.automotive.audiocontrol@2.0",
+    "android.hardware.automotive.can@1.0",  // converted to AIDL, see b/170405615
     "android.hardware.automotive.evs@1.1",
     "android.hardware.automotive.sv@1.0",
     "android.hardware.automotive.vehicle@2.0",
@@ -78,6 +75,7 @@
     "android.hardware.bluetooth@1.1", // converted to AIDL, see b/205758693
     "android.hardware.boot@1.2", // converted to AIDL, see b/227536004
     "android.hardware.broadcastradio@1.1",
+    "android.hardware.broadcastradio@2.0",
     "android.hardware.camera.provider@2.7", // Camera converted to AIDL, b/196432585
     "android.hardware.cas@1.2", // converted to AIDL, see b/227673974
     "android.hardware.cas.native@1.0",
@@ -136,13 +134,14 @@
     "android.hardware.vibrator@1.3",
     "android.hardware.vr@1.0",
     "android.hardware.weaver@1.0",
+    "android.hardware.wifi@1.6", // Converted to AIDL (see b/205044134)
     "android.hardware.wifi.hostapd@1.3", // Converted to AIDL (see b/194806512)
     "android.hardware.wifi.supplicant@1.4", // Converted to AIDL (see b/196235436)
-    "android.hardware.wifi.offload@1.0",
     "android.hidl.base@1.0",
     "android.hidl.memory.token@1.0",
     "android.system.net.netd@1.1", // Converted to AIDL (see b/205764585)
     "android.system.suspend@1.0", // Converted to AIDL (see b/170260236)
+    "android.system.wifi.keystore@1.0", // Converted to AIDL (see b/205764502)
 };
 // clang-format on
 
@@ -163,15 +162,13 @@
     /**
      * These types are only used in Android Automotive, so don't expect them
      * on phones.
-     * TODO(b/266868868) This test should run on Automotive devices to enforce
-     * the same requirements
      */
     "android.automotive.watchdog",
-    "android.frameworks.automotive.powerpolicy",
+    "android.frameworks.automotive.display",
     "android.frameworks.automotive.powerpolicy.internal",
     "android.frameworks.automotive.telemetry",
+    "android.hardware.automotive.audiocontrol",
     "android.hardware.automotive.can",
-    "android.hardware.automotive.evs",
     "android.hardware.broadcastradio",
     "android.hardware.automotive.occupant_awareness",
     "android.hardware.automotive.remoteaccess",
@@ -200,10 +197,12 @@
 
 /*
  * Always missing AIDL packages that are not served on Cuttlefish.
- * These are typically ypes-only packages.
+ * These are typically types-only packages.
  */
 static const std::set<std::string> kAlwaysMissingAidl = {
     // types-only packages, which never expect a default implementation
+    "android.frameworks.cameraservice.common",
+    "android.frameworks.cameraservice.device",
     "android.hardware.audio.common",
     "android.hardware.audio.core.sounddose",
     "android.hardware.biometrics.common",
@@ -219,6 +218,8 @@
     "android.hardware.uwb.fira_android",
     "android.hardware.keymaster",
     "android.hardware.automotive.vehicle.property",
+    // not on Cuttlefish since it's needed only on systems using HIDL audio HAL
+    "android.hardware.audio.sounddose",
 
     // android.hardware.media.bufferpool2 is a HAL-less interface.
     // It could be used for buffer recycling and caching by using the interface.
@@ -243,8 +244,6 @@
  * These must be accompanied by a bug and expected to be here temporarily.
  */
 static const std::vector<VersionedAidlPackage> kKnownMissingAidl = {
-    // No bug number for wifi - it's already done internally
-    {"android.hardware.wifi.", 1, 000000000},
     // Cuttlefish Identity Credential HAL implementation is currently
     // stuck at version 3 while RKP support is being added. Will be
     // updated soon.
@@ -255,11 +254,13 @@
     {"android.hardware.soundtrigger3.", 1, 266941225},
     {"android.media.soundtrigger.", 1, 266941225},
     {"android.hardware.media.c2.", 1, 251850069},
+    {"android.hardware.weaver.", 2, 262418065},
 
     {"android.automotive.computepipe.registry.", 2, 273549907},
     {"android.automotive.computepipe.runner.", 2, 273549907},
-    {"android.frameworks.automotive.display.", 1, 274161444},
-    {"android.hardware.automotive.audiocontrol.", 2, 0},
+    {"android.frameworks.automotive.powerpolicy.", 2, 274160980},
+    {"android.hardware.automotive.evs.", 2, 274162534},
+    {"android.hardware.automotive.ivn.", 1, 274139217},
 };
 
 // AOSP packages which are never considered
@@ -375,40 +376,6 @@
   return DeviceType::PHONE;
 }
 
-static std::set<std::string> getMissingHidl() {
-  static std::once_flag unionFlag;
-  static std::set<std::string> missingHidl = kKnownMissingHidl;
-
-  std::call_once(unionFlag, [&]() {
-    const DeviceType type = getDeviceType();
-    switch (type) {
-      case DeviceType::AUTOMOTIVE:
-        LOG(INFO) << "Determined this is an Automotive device";
-        break;
-      case DeviceType::TV:
-        missingHidl.insert(kAutomotiveOnlyHidl.begin(),
-                           kAutomotiveOnlyHidl.end());
-        LOG(INFO) << "Determined this is a TV device";
-        break;
-      case DeviceType::WATCH:
-        missingHidl.insert(kAutomotiveOnlyHidl.begin(),
-                           kAutomotiveOnlyHidl.end());
-        LOG(INFO) << "Determined this is a Wear device";
-        break;
-      case DeviceType::PHONE:
-        missingHidl.insert(kAutomotiveOnlyHidl.begin(),
-                           kAutomotiveOnlyHidl.end());
-        LOG(INFO) << "Determined this is a Phone device";
-        break;
-      case DeviceType::UNKNOWN:
-        CHECK(false) << "getDeviceType return UNKNOWN type.";
-        break;
-    }
-  });
-
-  return missingHidl;
-}
-
 static bool isMissingAidl(const std::string& packageName) {
   static std::once_flag unionFlag;
   static std::set<std::string> missingAidl = kAlwaysMissingAidl;
@@ -484,7 +451,7 @@
   // we'll be removing items from this which we know are missing
   // in order to be left with those elements which we thought we
   // knew were missing but are actually present
-  std::set<std::string> thoughtMissing = getMissingHidl();
+  std::set<std::string> thoughtMissing = kKnownMissingHidl;
 
   for (const FQName& f : allHidlManifestInterfaces()) {
     if (thoughtMissing.erase(f.getPackageAndVersion().string()) > 0) {
diff --git a/vsoc_x86_64_only/auto/aosp_cf.mk b/vsoc_x86_64_only/auto/aosp_cf.mk
index 5814867..b817e21 100644
--- a/vsoc_x86_64_only/auto/aosp_cf.mk
+++ b/vsoc_x86_64_only/auto/aosp_cf.mk
@@ -27,6 +27,10 @@
 # FIXME: Disable mainline path checks
 PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := false
 
+# HSUM is currently incompatible with telephony.
+# TODO(b/283853205): Properly disable telephony using per-partition makefile.
+TARGET_NO_TELEPHONY := true
+
 #
 # All components inherited here go to system_ext image
 #
diff --git a/vsoc_x86_64_only/auto_md/OWNERS b/vsoc_x86_64_only/auto_md/OWNERS
new file mode 100644
index 0000000..5482d9b
--- /dev/null
+++ b/vsoc_x86_64_only/auto_md/OWNERS
@@ -0,0 +1 @@
+include device/google/cuttlefish:/shared/auto_md/OWNERS
diff --git a/vsoc_x86_64_only/auto_md/aosp_cf.mk b/vsoc_x86_64_only/auto_md/aosp_cf.mk
new file mode 100644
index 0000000..c058498
--- /dev/null
+++ b/vsoc_x86_64_only/auto_md/aosp_cf.mk
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2022 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.
+#
+
+# Set board, as displays are set in the config_BOARD.json file (in
+# that file, display0 is main, display1 is cluster, and any other displays
+# are passenger displays - notice that the maximum allowed is 4 total).
+TARGET_BOARD_INFO_FILE := device/google/cuttlefish/shared/auto_md/android-info.txt
+
+PRODUCT_COPY_FILES += \
+    device/google/cuttlefish/shared/auto_md/display_settings.xml:$(TARGET_COPY_OUT_VENDOR)/etc/display_settings.xml
+
+PRODUCT_PACKAGE_OVERLAYS += \
+    device/google/cuttlefish/shared/auto_md/overlay
+
+# HSUM is currently incompatible with telephony.
+# TODO(b/283853205): Properly disable telephony using per-partition makefile.
+TARGET_NO_TELEPHONY := true
+
+ENABLE_CLUSTER_OS_DOUBLE:=true
+
+PRODUCT_PACKAGES += \
+    ClusterHomeSample \
+    ClusterOsDouble \
+    CarServiceOverlayEmulatorOsDouble \
+    CarServiceOverlayMdEmulatorOsDouble \
+    MultiDisplaySecondaryHomeTestLauncher \
+    MultiDisplayTest
+
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
+    com.android.car.internal.debug.num_auto_populated_users=1 # 1 passenger only (so 2nd display shows user picker)
+# TODO(b/233370174): add audio multi-zone
+#   ro.vendor.simulateMultiZoneAudio=true \
+
+
+# This will disable dynamic displays and enable hardcoded displays on hwservicemanager.
+$(call inherit-product, device/generic/car/emulator/cluster/cluster-hwservicemanager.mk)
+
+# Add the regular stuff.
+$(call inherit-product, device/google/cuttlefish/vsoc_x86_64_only/auto/aosp_cf.mk)
+
+PRODUCT_NAME := aosp_cf_x86_64_auto_md
+PRODUCT_MODEL := Cuttlefish x86_64 auto 64-bit only multi-displays
diff --git a/vsoc_x86_64_only/auto_mdnd/OWNERS b/vsoc_x86_64_only/auto_mdnd/OWNERS
new file mode 100644
index 0000000..5482d9b
--- /dev/null
+++ b/vsoc_x86_64_only/auto_mdnd/OWNERS
@@ -0,0 +1 @@
+include device/google/cuttlefish:/shared/auto_md/OWNERS
diff --git a/vsoc_x86_64_only/auto_mdnd/aosp_cf.mk b/vsoc_x86_64_only/auto_mdnd/aosp_cf.mk
new file mode 100644
index 0000000..a80d837
--- /dev/null
+++ b/vsoc_x86_64_only/auto_mdnd/aosp_cf.mk
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2023 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.
+#
+
+# TODO(b/264958209): for now it's just inheriting aosp_cf_md and setting
+# config_multiuserVisibleBackgroundUsersOnDefaultDisplay , but in the
+# long-run it should be customized further (for example, setting
+# occupancy zone and removing cluster and other unnecessary stuff)
+
+$(call inherit-product, device/google/cuttlefish/vsoc_x86_64_only/auto_md/aosp_cf.mk)
+
+# HSUM is currently incompatible with telephony.
+# TODO(b/283853205): Properly disable telephony using per-partition makefile.
+TARGET_NO_TELEPHONY := true
+
+PRODUCT_NAME := aosp_cf_x86_64_auto_mdnd
+PRODUCT_MODEL := Cuttlefish x86_64 auto 64-bit only multi-displays, no-driver
+
+PRODUCT_PACKAGE_OVERLAYS += \
+    device/google/cuttlefish/shared/auto_mdnd/overlay
diff --git a/vsoc_x86_64_only/auto_portrait/OWNERS b/vsoc_x86_64_only/auto_portrait/OWNERS
new file mode 100644
index 0000000..5bc897b
--- /dev/null
+++ b/vsoc_x86_64_only/auto_portrait/OWNERS
@@ -0,0 +1,4 @@
+include device/google/cuttlefish:/shared/auto/OWNERS
+babakbo@google.com
+calhuang@google.com
+priyanksingh@google.com
diff --git a/vsoc_x86_64_only/auto_portrait/aosp_cf.mk b/vsoc_x86_64_only/auto_portrait/aosp_cf.mk
new file mode 100644
index 0000000..dc8fb91
--- /dev/null
+++ b/vsoc_x86_64_only/auto_portrait/aosp_cf.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2023 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.
+#
+
+# AOSP Car UI Portrait Cuttlefish Target
+
+TARGET_BOARD_INFO_FILE := device/google/cuttlefish/shared/auto_portrait/android-info.txt
+
+PRODUCT_COPY_FILES += \
+    device/google/cuttlefish/shared/auto_portrait/display_settings.xml:$(TARGET_COPY_OUT_VENDOR)/etc/display_settings.xml
+
+# Exclude AAE Car System UI
+DO_NOT_INCLUDE_AAE_CAR_SYSTEM_UI := true
+
+# Exclude Car UI Reference Design
+DO_NOT_INCLUDE_CAR_UI_REFERENCE_DESIGN := true
+
+# Exclude Car Visual Overlay
+DISABLE_CAR_PRODUCT_VISUAL_OVERLAY := true
+
+# Copy additional files
+PRODUCT_COPY_FILES += \
+    packages/services/Car/car_product/car_ui_portrait/bootanimation/bootanimation.zip:system/media/bootanimation.zip
+
+$(call inherit-product, device/google/cuttlefish/vsoc_x86_64_only/auto/aosp_cf.mk)
+
+PRODUCT_NAME := aosp_cf_x86_64_only_auto_portrait
+PRODUCT_DEVICE := vsoc_x86_64_only
+PRODUCT_MANUFACTURER := Google
+PRODUCT_MODEL := AOSP Cuttlefish x86_64 auto 64-bit only with portrait UI
+
+$(call inherit-product, packages/services/Car/car_product/car_ui_portrait/apps/car_ui_portrait_apps.mk)
+$(call inherit-product, packages/services/Car/car_product/car_ui_portrait/rro/car_ui_portrait_rro.mk)
+
+PRODUCT_COPY_FILES += \
+    packages/services/Car/car_product/car_ui_portrait/android.software.car.splitscreen_multitasking.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.car.splitscreen_multitasking.xml
+
+# Include the`launch_cvd --config auto_portrait` option.
+$(call soong_config_append,cvd,launch_configs,cvd_config_auto_portrait.json)
\ No newline at end of file