Merge "Add tests for tunesTo in AIDL bcradio HAL utils" into main
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index bfa2783..e65ee77 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -118,8 +118,6 @@
 cc_binary {
     name: "android.hardware.audio.service-aidl.example",
     relative_install_path: "hw",
-    init_rc: ["android.hardware.audio.service-aidl.example.rc"],
-    vintf_fragments: ["android.hardware.audio.service-aidl.xml"],
     defaults: [
         "aidlaudioservice_defaults",
         "latest_android_hardware_audio_core_sounddose_ndk_shared",
@@ -146,6 +144,7 @@
         "-Wthread-safety",
         "-DBACKEND_NDK",
     ],
+    installable: false, //installed in apex com.android.hardware.audio
 }
 
 cc_test {
@@ -239,10 +238,9 @@
 cc_binary {
     name: "android.hardware.audio.effect.service-aidl.example",
     relative_install_path: "hw",
-    init_rc: ["android.hardware.audio.effect.service-aidl.example.rc"],
-    vintf_fragments: ["android.hardware.audio.effect.service-aidl.xml"],
     defaults: ["aidlaudioeffectservice_defaults"],
     shared_libs: [
+        "libapexsupport",
         "libtinyxml2",
     ],
     srcs: [
@@ -250,6 +248,7 @@
         "EffectFactory.cpp",
         "EffectMain.cpp",
     ],
+    installable: false, //installed in apex com.android.hardware.audio.effect
 }
 
 cc_library_headers {
@@ -258,3 +257,22 @@
     vendor_available: true,
     host_supported: true,
 }
+
+prebuilt_etc {
+    name: "android.hardware.audio.service-aidl.example.rc",
+    src: "android.hardware.audio.service-aidl.example.rc",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "android.hardware.audio.service-aidl.xml",
+    src: "android.hardware.audio.service-aidl.xml",
+    sub_dir: "vintf",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "audio_effects_config.xml",
+    src: "audio_effects_config.xml",
+    installable: false,
+}
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index 4a12f8a..1cc4897 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -24,6 +24,10 @@
 
 #include "effectFactory-impl/EffectConfig.h"
 
+#ifdef __ANDROID_APEX__
+#include <android/apexsupport.h>
+#endif
+
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioStreamType;
 using aidl::android::media::audio::common::AudioUuid;
@@ -89,6 +93,24 @@
 }
 
 bool EffectConfig::resolveLibrary(const std::string& path, std::string* resolvedPath) {
+    if (__builtin_available(android AAPEXSUPPORT_API, *)) {
+        AApexInfo *apexInfo;
+        if (AApexInfo_create(&apexInfo) == AAPEXINFO_OK) {
+            std::string apexName(AApexInfo_getName(apexInfo));
+            AApexInfo_destroy(apexInfo);
+            std::string candidatePath("/apex/");
+            candidatePath.append(apexName).append(kEffectLibApexPath).append(path);
+            LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
+            if (access(candidatePath.c_str(), R_OK) == 0) {
+                *resolvedPath = std::move(candidatePath);
+                return true;
+            }
+        }
+    } else {
+        LOG(DEBUG) << __func__ << " libapexsupport is not supported";
+    }
+
+    // If audio effects libs are not in vendor apex, locate them in kEffectLibPath
     for (auto* libraryDirectory : kEffectLibPath) {
         std::string candidatePath = std::string(libraryDirectory) + '/' + path;
         if (access(candidatePath.c_str(), R_OK) == 0) {
diff --git a/audio/aidl/default/EffectMain.cpp b/audio/aidl/default/EffectMain.cpp
index ca81204..ac178b6 100644
--- a/audio/aidl/default/EffectMain.cpp
+++ b/audio/aidl/default/EffectMain.cpp
@@ -21,15 +21,39 @@
 #include <android/binder_process.h>
 #include <system/audio_config.h>
 
+#ifdef __ANDROID_APEX__
+#include <android/apexsupport.h>
+#endif
+
 /** Default name of effect configuration file. */
 static const char* kDefaultConfigName = "audio_effects_config.xml";
 
+static inline std::string config_file_path() {
+    if (__builtin_available(android AAPEXSUPPORT_API, *)) {
+        AApexInfo *apexInfo;
+        if (AApexInfo_create(&apexInfo) == AAPEXINFO_OK) {
+            std::string apexName(AApexInfo_getName(apexInfo));
+            AApexInfo_destroy(apexInfo);
+            std::string candidatePath("/apex/");
+            candidatePath.append(apexName).append("/etc/").append(kDefaultConfigName);
+            LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
+            if (access(candidatePath.c_str(), R_OK) == 0) {
+                return std::move(candidatePath);
+            }
+        }
+    } else {
+        LOG(DEBUG) << __func__ << " libapexsupport is not supported";
+    }
+    LOG(DEBUG) << __func__ << ": Unable to resolve config file path in APEX";
+    return android::audio_find_readable_configuration_file(kDefaultConfigName);
+}
+
 int main() {
     // This is a debug implementation, always enable debug logging.
     android::base::SetMinimumLogSeverity(::android::base::DEBUG);
     ABinderProcess_setThreadPoolMaxThreadCount(0);
 
-    auto configFile = android::audio_find_readable_configuration_file(kDefaultConfigName);
+    auto configFile = config_file_path();
     if (configFile == "") {
         LOG(ERROR) << __func__ << ": config file " << kDefaultConfigName << " not found!";
         return EXIT_FAILURE;
diff --git a/audio/aidl/default/acousticEchoCanceler/Android.bp b/audio/aidl/default/acousticEchoCanceler/Android.bp
index 35d4a56..d0404cd 100644
--- a/audio/aidl/default/acousticEchoCanceler/Android.bp
+++ b/audio/aidl/default/acousticEchoCanceler/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
deleted file mode 100644
index 5f859a1..0000000
--- a/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
+++ /dev/null
@@ -1,11 +0,0 @@
-service vendor.audio-effect-hal-aidl /vendor/bin/hw/android.hardware.audio.effect.service-aidl.example
-    class hal
-    user audioserver
-    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
-    group audio media
-    capabilities BLOCK_SUSPEND
-    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
-    rlimit rtprio 10 10
-    ioprio rt 4
-    task_profiles ProcessCapacityHigh HighPerformance
-    onrestart restart audioserver
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml b/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
deleted file mode 100644
index 05a825d..0000000
--- a/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
-  <hal format="aidl">
-    <name>android.hardware.audio.effect</name>
-    <version>2</version>
-    <fqname>IFactory/default</fqname>
-  </hal>
-</manifest>
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
index 757976f..c3e19ba 100644
--- a/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
@@ -1,4 +1,5 @@
-service vendor.audio-hal-aidl /vendor/bin/hw/android.hardware.audio.service-aidl.example
+
+service vendor.audio-hal-aidl /apex/com.android.hardware.audio/bin/hw/android.hardware.audio.service-aidl.example
     class hal
     user audioserver
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
@@ -9,3 +10,15 @@
     ioprio rt 4
     task_profiles ProcessCapacityHigh HighPerformance
     onrestart restart audioserver
+
+service vendor.audio-effect-hal-aidl /apex/com.android.hardware.audio/bin/hw/android.hardware.audio.effect.service-aidl.example
+    class hal
+    user audioserver
+    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+    group audio media
+    capabilities BLOCK_SUSPEND
+    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+    rlimit rtprio 10 10
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh HighPerformance
+    onrestart restart audioserver
\ No newline at end of file
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml
index 2a51876..5278e4f 100644
--- a/audio/aidl/default/android.hardware.audio.service-aidl.xml
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml
@@ -31,4 +31,9 @@
     <fqname>IModule/usb</fqname>
   </hal>
   -->
+  <hal format="aidl">
+    <name>android.hardware.audio.effect</name>
+    <version>2</version>
+    <fqname>IFactory/default</fqname>
+  </hal>
 </manifest>
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
new file mode 100644
index 0000000..da84412
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
@@ -0,0 +1,49 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex {
+    name: "com.android.hardware.audio",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.key",
+    certificate: ":com.android.hardware.certificate",
+    updatable: false,
+    vendor: true,
+
+    binaries: [
+        "android.hardware.audio.service-aidl.example",
+        "android.hardware.audio.effect.service-aidl.example",
+    ],
+    native_shared_libs: [
+        "libaecsw",
+        "libagc1sw",
+        "libagc2sw",
+        "libbassboostsw",
+        "libbundleaidl",
+        "libdownmixaidl",
+        "libdynamicsprocessingaidl",
+        "libenvreverbsw",
+        "libequalizersw",
+        "libextensioneffect",
+        "libhapticgeneratoraidl",
+        "libloudnessenhanceraidl",
+        "libnssw",
+        "libpreprocessingaidl",
+        "libpresetreverbsw",
+        "libreverbaidl",
+        "libvirtualizersw",
+        "libvisualizeraidl",
+        "libvolumesw",
+    ],
+    prebuilts: [
+        "android.hardware.audio.service-aidl.example.rc",
+        "android.hardware.audio.service-aidl.xml",
+        "audio_effects_config.xml",
+    ],
+}
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/file_contexts b/audio/aidl/default/apex/com.android.hardware.audio/file_contexts
new file mode 100644
index 0000000..41a6ada
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/file_contexts
@@ -0,0 +1,4 @@
+(/.*)?                                                              u:object_r:vendor_file:s0
+/etc(/.*)?                                                          u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.audio\.service-aidl\.example             u:object_r:hal_audio_default_exec:s0
+/bin/hw/android\.hardware\.audio\.effect\.service-aidl\.example     u:object_r:hal_audio_default_exec:s0
\ No newline at end of file
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/manifest.json b/audio/aidl/default/apex/com.android.hardware.audio/manifest.json
new file mode 100644
index 0000000..42a2368
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.audio",
+    "version": 1
+}
diff --git a/audio/aidl/default/automaticGainControlV1/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
index 05c2c54..7b753eb 100644
--- a/audio/aidl/default/automaticGainControlV1/Android.bp
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/automaticGainControlV2/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
index dedc555..ea05152 100644
--- a/audio/aidl/default/automaticGainControlV2/Android.bp
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/bassboost/Android.bp b/audio/aidl/default/bassboost/Android.bp
index 9f47770..8f53eae 100644
--- a/audio/aidl/default/bassboost/Android.bp
+++ b/audio/aidl/default/bassboost/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/envReverb/Android.bp b/audio/aidl/default/envReverb/Android.bp
index 2443c2a..23495f1 100644
--- a/audio/aidl/default/envReverb/Android.bp
+++ b/audio/aidl/default/envReverb/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/equalizer/Android.bp b/audio/aidl/default/equalizer/Android.bp
index 42708d1..1d29d40 100644
--- a/audio/aidl/default/equalizer/Android.bp
+++ b/audio/aidl/default/equalizer/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/extension/Android.bp b/audio/aidl/default/extension/Android.bp
index 5fee479..2b21e3e 100644
--- a/audio/aidl/default/extension/Android.bp
+++ b/audio/aidl/default/extension/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index 344846a..7456b99 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -64,12 +64,16 @@
     const ProcessingLibrariesMap& getProcessingMap() const;
 
   private:
-    static constexpr const char* kEffectLibPath[] =
 #ifdef __LP64__
-            {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#define SOUND_FX_PATH "/lib64/soundfx/"
 #else
-            {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#define SOUND_FX_PATH "/lib/soundfx/"
 #endif
+    static constexpr const char* kEffectLibPath[] =
+      { "/odm" SOUND_FX_PATH, "/vendor" SOUND_FX_PATH, "/system" SOUND_FX_PATH };
+
+    static constexpr const char* kEffectLibApexPath = SOUND_FX_PATH;
+#undef SOUND_FX_PATH
 
     int mSkippedElements;
     /* Parsed Libraries result */
diff --git a/audio/aidl/default/noiseSuppression/Android.bp b/audio/aidl/default/noiseSuppression/Android.bp
index f24ded6..5729571 100644
--- a/audio/aidl/default/noiseSuppression/Android.bp
+++ b/audio/aidl/default/noiseSuppression/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/presetReverb/Android.bp b/audio/aidl/default/presetReverb/Android.bp
index d600141..2a2ae75 100644
--- a/audio/aidl/default/presetReverb/Android.bp
+++ b/audio/aidl/default/presetReverb/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/virtualizer/Android.bp b/audio/aidl/default/virtualizer/Android.bp
index 1c41bb5..5d59f7c 100644
--- a/audio/aidl/default/virtualizer/Android.bp
+++ b/audio/aidl/default/virtualizer/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/audio/aidl/default/volume/Android.bp b/audio/aidl/default/volume/Android.bp
index f1a051f..8d5401a 100644
--- a/audio/aidl/default/volume/Android.bp
+++ b/audio/aidl/default/volume/Android.bp
@@ -34,6 +34,6 @@
     ],
     relative_install_path: "soundfx",
     visibility: [
-        "//hardware/interfaces/audio/aidl/default",
+        "//hardware/interfaces/audio/aidl/default:__subpackages__",
     ],
 }
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 03f256e..ff7f41c 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -2010,6 +2010,13 @@
 
     // Test each reported camera
     for (auto&& cam: cameraInfo) {
+        bool isLogicalCam = false;
+        getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
+        if (isLogicalCam) {
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
+            continue;
+        }
+
         // Request exclusive access to the EVS display
         sp<IEvsDisplay_1_0> pDisplay = pEnumerator->openDisplay();
         ASSERT_NE(pDisplay, nullptr);
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index 8181e47..e3f7b5e 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -222,10 +222,9 @@
 
     // Lock our output buffer for writing
     uint8_t* pixels = nullptr;
-    int32_t bytesPerStride = 0;
     auto& mapper = ::android::GraphicBufferMapper::get();
     mapper.lock(renderBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
-                ::android::Rect(mWidth, mHeight), (void**)&pixels, nullptr, &bytesPerStride);
+                ::android::Rect(mWidth, mHeight), (void**)&pixels);
 
     // If we failed to lock the pixel buffer, we're about to crash, but log it first
     if (!pixels) {
@@ -247,13 +246,6 @@
         *(pixels++) = *(v_head++);
     }
 
-    const auto status =
-            AMediaCodec_releaseOutputBuffer(mVideoCodec.get(), index, /* render = */ false);
-    if (status != AMEDIA_OK) {
-        LOG(ERROR) << __func__
-                   << ": Received error in releasing output buffer. Error code: " << status;
-    }
-
     // Release our output buffer
     mapper.unlock(renderBufferHandle);
 
@@ -306,6 +298,12 @@
         return;
     }
     onCodecOutputAvailable(codecOutputputBufferIdx, info);
+    const auto release_status = AMediaCodec_releaseOutputBuffer(
+            mVideoCodec.get(), codecOutputputBufferIdx, /* render = */ false);
+    if (release_status != AMEDIA_OK) {
+        LOG(ERROR) << __func__
+                   << ": Received error in releasing output buffer. Error code: " << release_status;
+    }
 }
 
 void EvsVideoEmulatedCamera::initializeParameters() {
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
index 9834cdb..b0c6ae7 100644
--- a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
+++ b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IVehicle/default</fqname>
     </hal>
 </manifest>
diff --git a/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp
index a370436..f0cc9a2 100644
--- a/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp
+++ b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+#include "MockBroadcastRadioCallback.h"
+
 #include <BroadcastRadio.h>
 #include <VirtualRadio.h>
 #include <broadcastradio-utils-aidl/Utils.h>
 
+#include <android-base/logging.h>
 #include <gtest/gtest.h>
 
 namespace aidl::android::hardware::broadcastradio {
@@ -74,10 +77,19 @@
 class DefaultBroadcastRadioHalTest : public testing::Test {
   public:
     void SetUp() override {
+        ::android::base::SetDefaultTag("BcRadioAidlDef.test");
         const VirtualRadio& amFmRadioMockTest = getAmFmMockTestRadio();
         mBroadcastRadioHal = ::ndk::SharedRefBase::make<BroadcastRadio>(amFmRadioMockTest);
+        mTunerCallback = ndk::SharedRefBase::make<MockBroadcastRadioCallback>();
     }
+
+    void TearDown() override {
+        mBroadcastRadioHal->unsetTunerCallback();
+        EXPECT_FALSE(mTunerCallback->isTunerFailed());
+    }
+
     std::shared_ptr<BroadcastRadio> mBroadcastRadioHal;
+    std::shared_ptr<MockBroadcastRadioCallback> mTunerCallback;
 };
 
 TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfig) {
@@ -136,4 +148,24 @@
     }
 }
 
+TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallback) {
+    auto halResult = mBroadcastRadioHal->setTunerCallback(mTunerCallback);
+
+    ASSERT_TRUE(halResult.isOk());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallbackWithNull) {
+    auto halResult = mBroadcastRadioHal->setTunerCallback(nullptr);
+
+    ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, UnsetTunerCallbackWithNull) {
+    ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+
+    auto halResult = mBroadcastRadioHal->unsetTunerCallback();
+
+    ASSERT_TRUE(halResult.isOk());
+}
+
 }  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp
new file mode 100644
index 0000000..48f65fc
--- /dev/null
+++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 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 "MockBroadcastRadioCallback.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+using std::vector;
+}
+
+MockBroadcastRadioCallback::MockBroadcastRadioCallback() {
+    mAntennaConnectionState = true;
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onTuneFailed(Result result,
+                                                       const ProgramSelector& selector) {
+    LOG(DEBUG) << "onTuneFailed with result with " << selector.toString().c_str();
+    if (result != Result::CANCELED) {
+        std::lock_guard<std::mutex> lk(mLock);
+        tunerFailed = true;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+    LOG(DEBUG) << "onCurrentProgramInfoChanged with " << info.toString().c_str();
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        mCurrentProgramInfo = info;
+    }
+
+    mOnCurrentProgramInfoChangedFlag.notify();
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onProgramListUpdated(
+        [[maybe_unused]] const ProgramListChunk& chunk) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onParametersUpdated(
+        [[maybe_unused]] const vector<VendorKeyValue>& parameters) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onAntennaStateChange(bool connected) {
+    if (!connected) {
+        std::lock_guard<std::mutex> lk(mLock);
+        mAntennaConnectionState = false;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onConfigFlagUpdated([[maybe_unused]] ConfigFlag in_flag,
+                                                              [[maybe_unused]] bool in_value) {
+    return ndk::ScopedAStatus::ok();
+}
+
+bool MockBroadcastRadioCallback::waitOnCurrentProgramInfoChangedCallback() {
+    return mOnCurrentProgramInfoChangedFlag.wait();
+}
+
+void MockBroadcastRadioCallback::reset() {
+    mOnCurrentProgramInfoChangedFlag.reset();
+}
+
+bool MockBroadcastRadioCallback::isTunerFailed() {
+    std::lock_guard<std::mutex> lk(mLock);
+    return tunerFailed;
+}
+
+ProgramInfo MockBroadcastRadioCallback::getCurrentProgramInfo() {
+    std::lock_guard<std::mutex> lk(mLock);
+    return mCurrentProgramInfo;
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h
new file mode 100644
index 0000000..2ae03e3
--- /dev/null
+++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 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 <aidl/android/hardware/broadcastradio/BnTunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/ConfigFlag.h>
+#include <aidl/android/hardware/broadcastradio/IBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+#include <aidl/android/hardware/broadcastradio/VendorKeyValue.h>
+
+#include <android-base/thread_annotations.h>
+
+#include <broadcastradio-utils-aidl/Utils.h>
+
+#include <condition_variable>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+using ::ndk::ScopedAStatus;
+
+}  // namespace
+
+class MockBroadcastRadioCallback final : public BnTunerCallback {
+  public:
+    explicit MockBroadcastRadioCallback();
+    ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
+    ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
+    ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
+    ScopedAStatus onParametersUpdated(const std::vector<VendorKeyValue>& parameters) override;
+    ScopedAStatus onAntennaStateChange(bool connected) override;
+    ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override;
+
+    bool waitOnCurrentProgramInfoChangedCallback();
+    bool isTunerFailed();
+    void reset();
+
+    ProgramInfo getCurrentProgramInfo();
+
+  private:
+    class CallbackFlag final {
+      public:
+        CallbackFlag(int timeoutMs) { mTimeoutMs = timeoutMs; }
+        /**
+         * Notify that the callback is called.
+         */
+        void notify() {
+            std::unique_lock<std::mutex> lock(mMutex);
+            mCalled = true;
+            lock.unlock();
+            mCv.notify_all();
+        };
+
+        /**
+         * Wait for the timeout passed into the constructor.
+         */
+        bool wait() {
+            std::unique_lock<std::mutex> lock(mMutex);
+            return mCv.wait_for(lock, std::chrono::milliseconds(mTimeoutMs),
+                                [this] { return mCalled; });
+        };
+
+        /**
+         * Reset the callback to not called.
+         */
+        void reset() {
+            std::unique_lock<std::mutex> lock(mMutex);
+            mCalled = false;
+        }
+
+      private:
+        std::mutex mMutex;
+        bool mCalled GUARDED_BY(mMutex) = false;
+        std::condition_variable mCv;
+        int mTimeoutMs;
+    };
+
+    std::mutex mLock;
+    bool mAntennaConnectionState GUARDED_BY(mLock);
+    bool tunerFailed GUARDED_BY(mLock) = false;
+    ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock);
+    utils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
+    CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS);
+};
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index a6ec4c7..a16dd7f 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -789,8 +789,10 @@
                 outputBuffer.bufferId = buffer.bufferId;
                 outputBuffer.status = BufferStatus::ERROR;
                 if (buffer.acquireFence >= 0) {
-                    outputBuffer.releaseFence.fds.resize(1);
-                    outputBuffer.releaseFence.fds.at(0).set(buffer.acquireFence);
+                    native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                    handle->data[0] = buffer.acquireFence;
+                    outputBuffer.releaseFence = android::dupToAidl(handle);
+                    native_handle_delete(handle);
                 }
             } else {
                 offlineBuffers.push_back(buffer);
@@ -1389,12 +1391,14 @@
 
     // All buffers are imported. Now validate output buffer acquire fences
     for (size_t i = 0; i < numOutputBufs; i++) {
-        if (!sHandleImporter.importFence(
-                    ::android::makeFromAidl(request.outputBuffers[i].acquireFence), allFences[i])) {
+        native_handle_t* h = ::android::makeFromAidl(request.outputBuffers[i].acquireFence);
+        if (!sHandleImporter.importFence(h, allFences[i])) {
             ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
             cleanupInflightFences(allFences, i);
+            native_handle_delete(h);
             return Status::INTERNAL_ERROR;
         }
+        native_handle_delete(h);
     }
     return Status::OK;
 }
@@ -1768,8 +1772,10 @@
         result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
         result.outputBuffers[i].status = BufferStatus::ERROR;
         if (req->buffers[i].acquireFence >= 0) {
-            result.outputBuffers[i].releaseFence.fds.resize(1);
-            result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+            native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+            handle->data[0] = req->buffers[i].acquireFence;
+            result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+            native_handle_delete(handle);
         }
     }
 
@@ -1813,16 +1819,20 @@
         if (req->buffers[i].fenceTimeout) {
             result.outputBuffers[i].status = BufferStatus::ERROR;
             if (req->buffers[i].acquireFence >= 0) {
-                result.outputBuffers[i].releaseFence.fds.resize(1);
-                result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
             notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
         } else {
             result.outputBuffers[i].status = BufferStatus::OK;
             // TODO: refactor
             if (req->buffers[i].acquireFence >= 0) {
-                result.outputBuffers[i].releaseFence.fds.resize(1);
-                result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
         }
     }
@@ -2086,9 +2096,10 @@
                     // TODO: create a batch import API so we don't need to lock/unlock mCbsLock
                     // repeatedly?
                     lk.unlock();
-                    Status s =
-                            parent->importBuffer(streamId, hBuf.bufferId, makeFromAidl(hBuf.buffer),
-                                                 /*out*/ &mBufferReqs[i].bufPtr);
+                    native_handle_t* h = makeFromAidl(hBuf.buffer);
+                    Status s = parent->importBuffer(streamId, hBuf.bufferId, h,
+                                                    /*out*/ &mBufferReqs[i].bufPtr);
+                    native_handle_delete(h);
                     lk.lock();
 
                     if (s != Status::OK) {
@@ -2096,12 +2107,14 @@
                         cleanupInflightFences(importedFences, i - 1);
                         return false;
                     }
-                    if (!sHandleImporter.importFence(makeFromAidl(hBuf.acquireFence),
-                                                     mBufferReqs[i].acquireFence)) {
+                    h = makeFromAidl(hBuf.acquireFence);
+                    if (!sHandleImporter.importFence(h, mBufferReqs[i].acquireFence)) {
                         ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
                         cleanupInflightFences(importedFences, i - 1);
+                        native_handle_delete(h);
                         return false;
                     }
+                    native_handle_delete(h);
                     importedFences[i] = mBufferReqs[i].acquireFence;
                 } break;
                 default:
diff --git a/camera/device/default/ExternalCameraOfflineSession.cpp b/camera/device/default/ExternalCameraOfflineSession.cpp
index 53bd44f..2d4e2e0 100644
--- a/camera/device/default/ExternalCameraOfflineSession.cpp
+++ b/camera/device/default/ExternalCameraOfflineSession.cpp
@@ -110,7 +110,8 @@
             if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
                 handle->data[0] = req->buffers[i].acquireFence;
-                result.outputBuffers[i].releaseFence = android::makeToAidl(handle);
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
             notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
         } else {
@@ -119,7 +120,8 @@
             if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
                 handle->data[0] = req->buffers[i].acquireFence;
-                outputBuffer.releaseFence = android::makeToAidl(handle);
+                outputBuffer.releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
         }
     }
@@ -247,7 +249,8 @@
         if (req->buffers[i].acquireFence >= 0) {
             native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
             handle->data[0] = req->buffers[i].acquireFence;
-            outputBuffer.releaseFence = makeToAidl(handle);
+            outputBuffer.releaseFence = dupToAidl(handle);
+            native_handle_delete(handle);
         }
     }
 
diff --git a/camera/device/default/ExternalCameraUtils.cpp b/camera/device/default/ExternalCameraUtils.cpp
index 30c216f..2dc3c77 100644
--- a/camera/device/default/ExternalCameraUtils.cpp
+++ b/camera/device/default/ExternalCameraUtils.cpp
@@ -750,18 +750,12 @@
 
 void freeReleaseFences(std::vector<CaptureResult>& results) {
     for (auto& result : results) {
-        native_handle_t* inputReleaseFence =
-                ::android::makeFromAidl(result.inputBuffer.releaseFence);
-        if (inputReleaseFence != nullptr) {
-            native_handle_close(inputReleaseFence);
-            native_handle_delete(inputReleaseFence);
-        }
+        // NativeHandles free fd's on desctruction. Simply delete the objects!
+        result.inputBuffer.releaseFence.fds.clear();  // Implicitly closes fds
+        result.inputBuffer.releaseFence.ints.clear();
         for (auto& buf : result.outputBuffers) {
-            native_handle_t* outReleaseFence = ::android::makeFromAidl(buf.releaseFence);
-            if (outReleaseFence != nullptr) {
-                native_handle_close(outReleaseFence);
-                native_handle_delete(outReleaseFence);
-            }
+            buf.releaseFence.fds.clear();  // Implicitly closes fds
+            buf.releaseFence.ints.clear();
         }
     }
 }
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 4fc01bf..7958da9 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -316,14 +316,11 @@
 
 void CameraAidlTest::verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata) {
     camera_metadata_ro_entry entry;
-    // Check capabilities
-    int retcode =
-            find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
     bool hasStreamUseCaseCap = supportsStreamUseCaseCap(metadata);
 
     bool supportMandatoryUseCases = false;
-    retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
-                                            &entry);
+    int retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+                                                &entry);
     if ((0 == retcode) && (entry.count > 0)) {
         supportMandatoryUseCases = true;
         for (size_t i = 0; i < kMandatoryUseCases.size(); i++) {
diff --git a/health/OWNERS b/health/OWNERS
index 1d4d086..e540d55 100644
--- a/health/OWNERS
+++ b/health/OWNERS
@@ -1,6 +1,6 @@
 # Bug component: 30545
 
 apelosi@google.com
-elsk@google.com
+dvander@google.com
 smoreland@google.com
 wjack@google.com
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
index 5899a40..298cb13 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -35,6 +35,7 @@
 @VintfStability
 interface IClientManager {
   android.hardware.media.bufferpool2.IClientManager.Registration registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+  android.hardware.media.bufferpool2.IClientManager.Registration registerPassiveSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
   @VintfStability
   parcelable Registration {
     long connectionId;
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
index a3054cb..2bc77bc 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -40,7 +40,8 @@
     /**
      * Sets up a buffer receiving communication node for the specified
      * buffer pool. A manager must create a IConnection to the buffer
-     * pool if it does not already have a connection.
+     * pool if it does not already have a connection. To transfer buffers
+     * using the interface, the sender must initiates transfer.
      *
      * @param bufferPool a buffer pool which is specified with the IAccessor.
      *     The specified buffer pool is the owner of received buffers.
@@ -52,4 +53,21 @@
      *     ResultStatus::CRITICAL_ERROR   - Other errors.
      */
     Registration registerSender(in IAccessor bufferPool);
+
+    /**
+     * Sets up a buffer receiving communication node for the specified
+     * buffer pool. A manager must create a IConnection to the buffer
+     * pool if it does not already have a connection. To transfer buffers
+     * using the interface, the receiver must initiates transfer(on demand).
+     *
+     * @param bufferPool a buffer pool which is specified with the IAccessor.
+     *     The specified buffer pool is the owner of received buffers.
+     * @return the Id of the communication node to the buffer pool.
+     *     This id is used in FMQ to notify IAccessor that a buffer has been
+     *     sent to that connection during transfers.
+     * @throws ServiceSpecificException with one of the following values:
+     *     ResultStatus::NO_MEMORY        - Memory allocation failure occurred.
+     *     ResultStatus::CRITICAL_ERROR   - Other errors.
+     */
+    Registration registerPassiveSender(in IAccessor bufferPool);
 }
diff --git a/media/bufferpool/aidl/default/ClientManager.cpp b/media/bufferpool/aidl/default/ClientManager.cpp
index de1db50..138790d 100644
--- a/media/bufferpool/aidl/default/ClientManager.cpp
+++ b/media/bufferpool/aidl/default/ClientManager.cpp
@@ -422,6 +422,14 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus ClientManager::registerPassiveSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
+    // TODO
+    (void) in_bufferPool;
+    (void) _aidl_return;
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::NOT_FOUND);
+}
+
 // Methods for local use.
 std::shared_ptr<ClientManager> ClientManager::sInstance;
 std::mutex ClientManager::sInstanceLock;
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
index bff75ba..4b0916f 100644
--- a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
+++ b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
@@ -34,6 +34,11 @@
         ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
         override;
 
+    ::ndk::ScopedAStatus registerPassiveSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool,
+        ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
+        override;
+
     /** Gets an instance. */
     static std::shared_ptr<ClientManager> getInstance();
 
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
index 4439bc5..0a7e3c4 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
@@ -51,12 +51,18 @@
     long blockPoolId;
     android.hardware.media.c2.IConfigurable configurable;
   }
-  parcelable C2AidlGbAllocator {
-    android.hardware.media.c2.IGraphicBufferAllocator igba;
+  parcelable GbAllocator {
     ParcelFileDescriptor waitableFd;
+    android.hardware.media.c2.IGraphicBufferAllocator igba;
   }
-  union BlockPoolAllocator {
+  parcelable PooledGbAllocator {
+    ParcelFileDescriptor waitableFd;
+    long receiverId;
+    android.hardware.media.c2.IPooledGraphicBufferAllocator ipgba;
+  }
+  parcelable BlockPoolAllocator {
     int allocatorId;
-    android.hardware.media.c2.IComponent.C2AidlGbAllocator allocator;
+    @nullable android.hardware.media.c2.IComponent.GbAllocator gbAllocator;
+    @nullable android.hardware.media.c2.IComponent.PooledGbAllocator pooledGbAllocator;
   }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..1a8c66d
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.c2;
+@VintfStability
+interface IPooledGraphicBufferAllocator {
+  android.hardware.media.c2.IPooledGraphicBufferAllocator.Allocation allocate(in android.hardware.media.c2.IPooledGraphicBufferAllocator.Description desc);
+  boolean deallocate(in int id);
+  parcelable Allocation {
+    int bufferId;
+    @nullable ParcelFileDescriptor fence;
+  }
+  parcelable Description {
+    int widthPixels;
+    int heightPixels;
+    int format;
+    long usage;
+  }
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
index ed2eaf4..387d70a 100644
--- a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -24,6 +24,7 @@
 import android.hardware.media.c2.IInputSink;
 import android.hardware.media.c2.IInputSurface;
 import android.hardware.media.c2.IInputSurfaceConnection;
+import android.hardware.media.c2.IPooledGraphicBufferAllocator;
 import android.hardware.media.c2.WorkBundle;
 import android.os.ParcelFileDescriptor;
 
@@ -57,20 +58,36 @@
      * graphic blocks. the waitable fd is used to create a specific type of
      * C2Fence which can be used for waiting until to allocate is not blocked.
      */
-    parcelable C2AidlGbAllocator {
-        IGraphicBufferAllocator igba;
+    parcelable GbAllocator {
         ParcelFileDescriptor waitableFd;
+        IGraphicBufferAllocator igba;
     }
 
     /**
+     * C2AIDL allocator interface based on media.bufferpool2 along with a waitable fd.
+     *
+     * The interface is used from a specific type of C2BlockPool to allocate
+     * graphic blocks. the waitable fd is used to create a specific type of
+     * C2Fence which can be used for waiting until to allocate is not blocked.
+     * receiverId is id of receiver IConnection of media.bufferpool2.
+     */
+    parcelable PooledGbAllocator {
+        ParcelFileDescriptor waitableFd;
+        long receiverId;
+        IPooledGraphicBufferAllocator ipgba;
+    }
+
+
+    /**
      * Allocator for C2BlockPool.
      *
      * C2BlockPool will use a C2Allocator which is specified by an id.
-     * or C2AIDL allocator interface directly.
+     * Based on allocator id, allocator is specified.
      */
-    union BlockPoolAllocator {
+    parcelable BlockPoolAllocator {
         int allocatorId;
-        C2AidlGbAllocator allocator;
+        @nullable GbAllocator gbAllocator;
+        @nullable PooledGbAllocator pooledGbAllocator;
     }
 
     /**
diff --git a/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl b/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..b599d52
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.media.c2;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for decoder output buffer allocator for HAL process
+ *
+ * A graphic buffer for decoder output is allocated by the interface.
+ */
+@VintfStability
+interface IPooledGraphicBufferAllocator {
+    /**
+     * A graphic buffer allocation.
+     *
+     * bufferId is id of buffer from a media.bufferpool2. The buffer is
+     * android.hardware.HardwareBuffer.
+     * fence is provided in order to signal readiness of the buffer I/O inside
+     * underlying Graphics subsystem. This is called a sync fence throughout Android framework.
+     */
+    parcelable Allocation {
+        int bufferId;
+        @nullable ParcelFileDescriptor fence;
+    }
+
+    /**
+     * Parameters for a graphic buffer allocation.
+     *
+     * Refer to AHardwareBuffer_Desc(libnativewindow) for details.
+     */
+    parcelable Description {
+        int widthPixels;
+        int heightPixels;
+        int format; // AHardwareBuffer_Format
+        long usage; // AHardwareBuffer_UsageFlags
+    }
+
+    /**
+     * Allocate a graphic buffer.
+     * deallocate() must be called after the allocated buffer is no longer needed.
+     *
+     * @param desc Allocation parameters.
+     * @return an id of a buffer, the id is created from media.bufferpool2 in order for
+     *     caching and recycling,
+     *     If underlying allocator is blocked, c2::Status::Blocked will be returned.
+     *     Waitable fd must be obtained using the ndk object locally. The waitable fd must
+     *     be passed to the receiver during BlockPool creation request via AIDL.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `c2::Status::BAD_STATE` - The client is not in running states.
+     *   - `c2::Status::BLOCKED`   - Underlying graphics system is blocked.
+     *   - `c2::Status::CORRUPTED` - Some unknown error occurred.
+     */
+    Allocation allocate(in Description desc);
+
+    /**
+     * De-allocate a graphic buffer by graphic buffer's unique id.
+     *
+     * @param id buffer id.
+     * @return {@code true} when de-allocate happened, {@code false} otherwise.
+     */
+    boolean deallocate(in int id);
+}
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index f24c6d1..9a75e6e 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -630,10 +630,7 @@
         if (error != android::NO_ERROR) return 1;
     } else {
         void* data;
-        int32_t outBytesPerPixel;
-        int32_t outBytesPerStride;
-        error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data,
-                              &outBytesPerPixel, &outBytesPerStride);
+        error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data);
         EXPECT_EQ(error, android::NO_ERROR);
         if (error != android::NO_ERROR) return 1;
 
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
index eedb8ed..1529512 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
@@ -42,9 +42,13 @@
   NAS_SIGNALLING_LTE = 4,
   AS_SIGNALLING_LTE = 5,
   VOLTE_SIP = 6,
-  VOLTE_RTP = 7,
-  NAS_SIGNALLING_5G = 8,
-  AS_SIGNALLING_5G = 9,
-  VONR_SIP = 10,
-  VONR_RTP = 11,
+  VOLTE_SIP_SOS = 7,
+  VOLTE_RTP = 8,
+  VOLTE_RTP_SOS = 9,
+  NAS_SIGNALLING_5G = 10,
+  AS_SIGNALLING_5G = 11,
+  VONR_SIP = 12,
+  VONR_SIP_SOS = 13,
+  VONR_RTP = 14,
+  VONR_RTP_SOS = 15,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
index c590d2b..c3333bf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -57,6 +57,7 @@
   NEA1 = 56,
   NEA2 = 57,
   NEA3 = 58,
+  SIP_NO_IPSEC_CONFIG = 66,
   IMS_NULL = 67,
   SIP_NULL = 68,
   AES_GCM = 69,
@@ -66,6 +67,7 @@
   AES_EDE3_CBC = 73,
   HMAC_SHA1_96 = 74,
   HMAC_MD5_96 = 75,
+  RTP = 85,
   SRTP_NULL = 86,
   SRTP_AES_COUNTER = 87,
   SRTP_AES_F8 = 88,
diff --git a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
index 2e39ebf..d5f367f 100644
--- a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
@@ -42,14 +42,20 @@
     AS_SIGNALLING_LTE = 5,
 
     // VoLTE
+    // Note: emergency calls could use either normal or SOS (emergency) PDN in practice
     VOLTE_SIP = 6,
-    VOLTE_RTP = 7,
+    VOLTE_SIP_SOS = 7,
+    VOLTE_RTP = 8,
+    VOLTE_RTP_SOS = 9,
 
     // 5G packet services
-    NAS_SIGNALLING_5G = 8,
-    AS_SIGNALLING_5G = 9,
+    NAS_SIGNALLING_5G = 10,
+    AS_SIGNALLING_5G = 11,
 
     // VoNR
-    VONR_SIP = 10,
-    VONR_RTP = 11,
+    // Note: emergency calls could use either normal or SOS (emergency) PDN in practice
+    VONR_SIP = 12,
+    VONR_SIP_SOS = 13,
+    VONR_RTP = 14,
+    VONR_RTP_SOS = 15
 }
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
index 19feeef..01f7327 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -60,7 +60,11 @@
     NEA3 = 58,
 
     // IMS and SIP layer security (See 3GPP TS 33.203)
+    // No IPsec config
+    SIP_NO_IPSEC_CONFIG = 66,
     IMS_NULL = 67,
+
+    // Has IPsec config
     SIP_NULL = 68,
     AES_GCM = 69,
     AES_GMAC = 70,
@@ -70,7 +74,10 @@
     HMAC_SHA1_96 = 74,
     HMAC_MD5_96 = 75,
 
-    // RTP (see 3GPP TS 33.328)
+    // RTP and SRTP (see 3GPP TS 33.328)
+    // When SRTP is not being used
+    RTP = 85,
+    // When SRTP is available and used
     SRTP_NULL = 86,
     SRTP_AES_COUNTER = 87,
     SRTP_AES_F8 = 88,
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 2e218c0..867be04 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -883,7 +883,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -909,7 +909,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -934,7 +934,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 470ee73..ad530eb 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -38,16 +38,16 @@
     RadioResponseInfo rspInfo;
     std::vector<RadioBandMode> radioBandModes;
     std::vector<OperatorInfo> networkInfos;
-    bool isNrDualConnectivityEnabled;
-    int networkTypeBitmapResponse;
+    bool isNrDualConnectivityEnabled = false;
+    int networkTypeBitmapResponse = 0;
     RegStateResult voiceRegResp;
     RegStateResult dataRegResp;
     CellIdentity barringCellIdentity;
     std::vector<BarringInfo> barringInfoList;
     UsageSetting usageSetting;
     std::vector<RadioAccessSpecifier> specifiers;
-    bool isCellularIdentifierTransparencyEnabled;
-    bool isSecurityAlgorithmsUpdatedEnabled;
+    bool isCellularIdentifierTransparencyEnabled = false;
+    bool isSecurityAlgorithmsUpdatedEnabled = false;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;