Merge changes from topic "isap_hidl2aidl"

* changes:
  [ISap hidl2aidl] VTS Tests
  [ISap hidl2aidl] Compat Support
  Radio: hidl2aidl for ISap interface
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 6b948dd..2ed711a 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -114,6 +114,7 @@
         "android/hardware/audio/core/AudioRoute.aidl",
         "android/hardware/audio/core/IConfig.aidl",
         "android/hardware/audio/core/IModule.aidl",
+        "android/hardware/audio/core/ISoundDose.aidl",
         "android/hardware/audio/core/IStreamCallback.aidl",
         "android/hardware/audio/core/IStreamIn.aidl",
         "android/hardware/audio/core/IStreamOut.aidl",
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index 0c7ca27..42b12d9 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -60,6 +60,7 @@
   void updateAudioMode(android.hardware.audio.core.AudioMode mode);
   void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
   void updateScreenState(boolean isTurnedOn);
+  @nullable android.hardware.audio.core.ISoundDose getSoundDose();
   @VintfStability
   parcelable OpenInputStreamArguments {
     int portConfigId;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
new file mode 100644
index 0000000..bc010ca
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.audio.core;
+@VintfStability
+interface ISoundDose {
+  void setOutputRs2(float rs2ValueDbA);
+  float getOutputRs2();
+  void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
+  const int DEFAULT_MAX_RS2 = 100;
+  const int MIN_RS2 = 80;
+  @VintfStability
+  interface IHalSoundDoseCallback {
+    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    @VintfStability
+    parcelable MelRecord {
+      float[] melValues;
+      long timestamp;
+    }
+  }
+}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 786d5ee..2d34df6 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -21,6 +21,7 @@
 import android.hardware.audio.core.AudioMode;
 import android.hardware.audio.core.AudioPatch;
 import android.hardware.audio.core.AudioRoute;
+import android.hardware.audio.core.ISoundDose;
 import android.hardware.audio.core.IStreamCallback;
 import android.hardware.audio.core.IStreamIn;
 import android.hardware.audio.core.IStreamOut;
@@ -668,4 +669,19 @@
      * @param isTurnedOn True if the screen is turned on.
      */
     void updateScreenState(boolean isTurnedOn);
+
+    /**
+     * Retrieve the sound dose interface.
+     *
+     * If a device must comply to IEC62368-1 3rd edition audio safety requirements and is
+     * implementing audio offload decoding or other direct playback paths where volume control
+     * happens below the audio HAL, it must return an instance of the ISoundDose interface.
+     * The same instance must be returned during the lifetime of the HAL module.
+     * If the HAL module does not support sound dose, null must be returned, without throwing
+     * any errors.
+     *
+     * @return An instance of the ISoundDose interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable ISoundDose getSoundDose();
 }
diff --git a/audio/aidl/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/android/hardware/audio/core/ISoundDose.aidl
new file mode 100644
index 0000000..89fd69b
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/ISoundDose.aidl
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.AudioDevice;
+
+/**
+ * This interface provides functions related to sound exposure control required for compliance to
+ * EN/IEC 62368-1 3rd edition. Implementing this interface is mandatory for devices for which
+ * compliance to this standard is mandated and implementing audio offload decoding or other direct
+ * playback paths where volume control happens below the audio HAL.
+ */
+@VintfStability
+interface ISoundDose {
+    /**
+     * Max value in dBA used for momentary exposure warnings as defined by IEC62368-1
+     * 3rd edition. This value represents the default RS2 value.
+     */
+    const int DEFAULT_MAX_RS2 = 100;
+    /** Min value of the RS2 threshold in dBA as defined by IEC62368-1 3rd edition. */
+    const int MIN_RS2 = 80;
+
+    /**
+     * Sets the RS2 value used for momentary exposure warnings. Default value is
+     * DEFAULT_MAX_RS2 as specified in IEC62368-1 3rd edition.
+     *
+     * @param rs2ValueDbA custom RS2 value to use. Must not be higher than DEFAULT_MAX_RS2
+     * @throws EX_ILLEGAL_ARGUMENT if rs2ValueDbA is greater than DEFAULT_MAX_RS2 or lower
+     *                             than 80dBA
+     */
+    void setOutputRs2(float rs2ValueDbA);
+
+    /**
+     * Gets the RS2 value used for momentary exposure warnings.
+     *
+     * @return the RS2 value in dBA
+     */
+    float getOutputRs2();
+
+    /**
+     * Registers the HAL callback for sound dose computation. If sound dose is supported
+     * the MEL values and exposure notifications will be received through this callback
+     * only. The internal framework MEL computation will be disabled.
+     * It is not possible to unregister the callback. The HAL is responsible to provide
+     * the MEL values throughout its lifecycle.
+     * This method should only be called once (no updates allowed) with a valid callback.
+     *
+     * @param callback to use when new updates are available for sound dose
+     * @throws EX_ILLEGAL_STATE if the method is called more than once
+     * @throws EX_ILLEGAL_ARGUMENT if the passed callback is null
+     */
+    void registerSoundDoseCallback(in IHalSoundDoseCallback callback);
+
+    @VintfStability
+    oneway interface IHalSoundDoseCallback {
+        /**
+         * Called whenever the current MEL value exceeds the set RS2 value.
+         *
+         * @param currentDbA the current MEL value which exceeds the RS2 value
+         * @param audioDevice the audio device where the MEL exposure warning was recorded
+         */
+        void onMomentaryExposureWarning(float currentDbA, in AudioDevice audioDevice);
+
+        @VintfStability
+        parcelable MelRecord {
+            /**
+             * Array of continuously recorded MEL values >= RS1 (1 per second).
+             * First value in the array was recorded at 'timestamp'.
+             */
+            float[] melValues;
+            /**
+             * Corresponds to the time in seconds when the first MEL entry in melValues
+             * was recorded. The timestamp values have to be consistent throughout all
+             * audio ports, equal timestamp values will be aggregated.
+             */
+            long timestamp;
+        }
+
+        /**
+         * Provides a MelRecord containing continuous MEL values sorted by timestamp.
+         * Note that all the MEL values originate from the audio device specified by audioDevice.
+         * In case values from multiple devices need to be reported, the caller should execute
+         * this callback once for every device.
+         *
+         * @param melRecord contains the MEL values used for CSD
+         * @param audioDevice the audio device where the MEL values were recorded
+         */
+        void onNewMelValues(in MelRecord melRecord, in AudioDevice audioDevice);
+    }
+}
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 1026134..990cff9 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -20,6 +20,7 @@
 #include <type_traits>
 
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceType.h>
 #include <aidl/android/media/audio/common/AudioFormatDescription.h>
 #include <aidl/android/media/audio/common/AudioInputFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
@@ -83,6 +84,12 @@
     return 0;
 }
 
+constexpr bool isTelephonyDeviceType(
+        ::aidl::android::media::audio::common::AudioDeviceType device) {
+    return device == ::aidl::android::media::audio::common::AudioDeviceType::IN_TELEPHONY_RX ||
+           device == ::aidl::android::media::audio::common::AudioDeviceType::OUT_TELEPHONY_TX;
+}
+
 // The helper functions defined below are only applicable to the case when an enum type
 // specifies zero-based bit positions, not bit masks themselves. This is why instantiation
 // is restricted to certain enum types.
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index f2cebbf..b9b8cd8 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -43,6 +43,7 @@
         "Configuration.cpp",
         "EngineConfigXmlConverter.cpp",
         "Module.cpp",
+        "SoundDose.cpp",
         "Stream.cpp",
         "Telephony.cpp",
     ],
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 280814f..6d5357b 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -115,85 +115,150 @@
     return config;
 }
 
-static AudioRoute createRoute(const std::vector<int32_t>& sources, int32_t sink) {
+static AudioRoute createRoute(const std::vector<AudioPort>& sources, const AudioPort& sink) {
     AudioRoute route;
-    route.sinkPortId = sink;
-    route.sourcePortIds.insert(route.sourcePortIds.end(), sources.begin(), sources.end());
+    route.sinkPortId = sink.id;
+    std::transform(sources.begin(), sources.end(), std::back_inserter(route.sourcePortIds),
+                   [](const auto& port) { return port.id; });
     return route;
 }
 
-// Configuration:
+// Primary (default) configuration:
 //
 // Device ports:
-//  * "Null", OUT_SPEAKER, default
+//  * "Speaker", OUT_SPEAKER, default
 //    - no profiles specified
-//  * "Loopback Out", OUT_SUBMIX
-//    - profile PCM 24-bit; STEREO; 48000
+//  * "Built-in Mic", IN_MICROPHONE, default
+//    - no profiles specified
+//  * "Telephony Tx", OUT_TELEPHONY_TX
+//    - no profiles specified
+//  * "Telephony Rx", IN_TELEPHONY_RX
+//    - no profiles specified
+//  * "FM Tuner", IN_FM_TUNER
+//    - no profiles specified
 //  * "USB Out", OUT_DEVICE, CONNECTION_USB
 //    - no profiles specified
-//  * "Zero", IN_MICROPHONE, default
-//    - no profiles specified
-//  * "Loopback In", IN_SUBMIX
-//    - profile PCM 24-bit; STEREO; 48000
 //  * "USB In", IN_DEVICE, CONNECTION_USB
 //    - no profiles specified
 //
 // Mix ports:
 //  * "primary output", PRIMARY, 1 max open, 1 max active stream
-//    - profile PCM 16-bit; MONO, STEREO; 44100, 48000
-//    - profile PCM 24-bit; MONO, STEREO; 44100, 48000
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //  * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
 //    - profile MP3; MONO, STEREO; 44100, 48000
-//  * "loopback output", stream count unlimited
-//    - profile PCM 24-bit; STEREO; 48000
 //  * "primary input", 2 max open, 2 max active streams
 //    - profile PCM 16-bit; MONO, STEREO, FRONT_BACK;
 //        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
 //    - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
 //        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
-//  * "loopback input", stream count unlimited
-//    - profile PCM 24-bit; STEREO; 48000
+//  * "telephony_tx", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * "telephony_rx", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * "fm_tuner", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //
 // Routes:
-//  "primary out", "compressed offload" -> "Null"
+//  "primary out", "compressed offload" -> "Speaker"
 //  "primary out", "compressed offload" -> "USB Out"
-//  "loopback out" -> "Loopback Out"
-//  "Zero", "USB In" -> "primary input"
-//  "Loopback In" -> "loopback input"
+//  "Built-in Mic", "USB In" -> "primary input"
+//  "telephony_tx" -> "Telephony Tx"
+//  "Telephony Rx" -> "telephony_rx"
+//  "FM Tuner" -> "fm_tuner"
 //
 // Initial port configs:
-//  * "Null" device port: PCM 24-bit; STEREO; 48000
-//  * "Zero" device port: PCM 24-bit; MONO; 48000
+//  * "Speaker" device port: PCM 24-bit; STEREO; 48000
+//  * "Built-in Mic" device port: PCM 24-bit; MONO; 48000
+//  * "Telephony Tx" device port: PCM 24-bit; MONO; 48000
+//  * "Telephony Rx" device port: PCM 24-bit; MONO; 48000
+//  * "FM Tuner" device port: PCM 24-bit; STEREO; 48000
 //
 // Profiles for device port connected state:
 //  * USB Out":
-//    - profile PCM 16-bit; MONO, STEREO; 44100, 48000
-//    - profile PCM 24-bit; MONO, STEREO; 44100, 48000
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //  * USB In":
-//    - profile PCM 16-bit; MONO, STEREO; 44100, 48000
-//    - profile PCM 24-bit; MONO, STEREO; 44100, 48000
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //
-Configuration& getNullPrimaryConfiguration() {
-    static Configuration configuration = []() {
+std::unique_ptr<Configuration> getPrimaryConfiguration() {
+    static const Configuration configuration = []() {
         const std::vector<AudioProfile> standardPcmAudioProfiles = {
                 createProfile(PcmType::INT_16_BIT,
                               {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
-                              {44100, 48000}),
+                              {8000, 11025, 16000, 32000, 44100, 48000}),
                 createProfile(PcmType::INT_24_BIT,
                               {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
-                              {44100, 48000})};
+                              {8000, 11025, 16000, 32000, 44100, 48000})};
         Configuration c;
 
-        AudioPort nullOutDevice =
-                createPort(c.nextPortId++, "Null", 0, false,
+        // Device ports
+
+        AudioPort speakerOutDevice =
+                createPort(c.nextPortId++, "Speaker", 0, false,
                            createDeviceExt(AudioDeviceType::OUT_SPEAKER,
                                            1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
-        c.ports.push_back(nullOutDevice);
+        c.ports.push_back(speakerOutDevice);
         c.initialConfigs.push_back(
-                createPortConfig(nullOutDevice.id, nullOutDevice.id, PcmType::INT_24_BIT,
+                createPortConfig(speakerOutDevice.id, speakerOutDevice.id, PcmType::INT_24_BIT,
                                  AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
                                  createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
 
+        AudioPort micInDevice =
+                createPort(c.nextPortId++, "Built-in Mic", 0, true,
+                           createDeviceExt(AudioDeviceType::IN_MICROPHONE,
+                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
+        c.ports.push_back(micInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(micInDevice.id, micInDevice.id, PcmType::INT_24_BIT,
+                                 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
+                                 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
+
+        AudioPort telephonyTxOutDevice =
+                createPort(c.nextPortId++, "Telephony Tx", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0));
+        c.ports.push_back(telephonyTxOutDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(telephonyTxOutDevice.id, telephonyTxOutDevice.id,
+                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
+                                 false, createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0)));
+
+        AudioPort telephonyRxInDevice =
+                createPort(c.nextPortId++, "Telephony Rx", 0, true,
+                           createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0));
+        c.ports.push_back(telephonyRxInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(telephonyRxInDevice.id, telephonyRxInDevice.id,
+                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
+                                 true, createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0)));
+
+        AudioPort fmTunerInDevice = createPort(c.nextPortId++, "FM Tuner", 0, true,
+                                               createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0));
+        c.ports.push_back(fmTunerInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(fmTunerInDevice.id, fmTunerInDevice.id, PcmType::INT_24_BIT,
+                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, true,
+                                 createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0)));
+
+        AudioPort usbOutDevice =
+                createPort(c.nextPortId++, "USB Out", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
+                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbOutDevice);
+        c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
+
+        AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true,
+                                           createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
+                                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbInDevice);
+        c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
+
+        // Mix ports
+
         AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
                                              makeBitPositionFlagMask(AudioOutputFlags::PRIMARY),
                                              false, createPortMixExt(1, 1));
@@ -214,42 +279,6 @@
                               {44100, 48000}));
         c.ports.push_back(compressedOffloadOutMix);
 
-        AudioPort loopOutDevice = createPort(c.nextPortId++, "Loopback Out", 0, false,
-                                             createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
-        loopOutDevice.profiles.push_back(
-                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
-        c.ports.push_back(loopOutDevice);
-
-        AudioPort loopOutMix =
-                createPort(c.nextPortId++, "loopback output", 0, false, createPortMixExt(0, 0));
-        loopOutMix.profiles.push_back(
-                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
-        c.ports.push_back(loopOutMix);
-
-        AudioPort usbOutDevice =
-                createPort(c.nextPortId++, "USB Out", 0, false,
-                           createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
-                                           AudioDeviceDescription::CONNECTION_USB));
-        c.ports.push_back(usbOutDevice);
-        c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
-
-        AudioPort zeroInDevice =
-                createPort(c.nextPortId++, "Zero", 0, true,
-                           createDeviceExt(AudioDeviceType::IN_MICROPHONE,
-                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
-        c.ports.push_back(zeroInDevice);
-        c.initialConfigs.push_back(
-                createPortConfig(zeroInDevice.id, zeroInDevice.id, PcmType::INT_24_BIT,
-                                 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
-                                 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
-
-        MicrophoneInfo mic;
-        mic.id = "zero";
-        mic.device = zeroInDevice.ext.get<AudioPortExt::Tag::device>().device;
-        mic.group = 0;
-        mic.indexInTheGroup = 0;
-        c.microphones = std::vector<MicrophoneInfo>{mic};
-
         AudioPort primaryInMix =
                 createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
         primaryInMix.profiles.push_back(
@@ -264,36 +293,104 @@
                               {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
         c.ports.push_back(primaryInMix);
 
-        AudioPort loopInDevice = createPort(c.nextPortId++, "Loopback In", 0, true,
-                                            createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
-        loopInDevice.profiles.push_back(
-                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
-        c.ports.push_back(loopInDevice);
+        AudioPort telephonyTxOutMix =
+                createPort(c.nextPortId++, "telephony_tx", 0, false, createPortMixExt(1, 1));
+        telephonyTxOutMix.profiles.insert(telephonyTxOutMix.profiles.begin(),
+                                          standardPcmAudioProfiles.begin(),
+                                          standardPcmAudioProfiles.end());
+        c.ports.push_back(telephonyTxOutMix);
 
-        AudioPort loopInMix =
-                createPort(c.nextPortId++, "loopback input", 0, true, createPortMixExt(0, 0));
-        loopInMix.profiles.push_back(
-                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
-        c.ports.push_back(loopInMix);
+        AudioPort telephonyRxInMix =
+                createPort(c.nextPortId++, "telephony_rx", 0, true, createPortMixExt(1, 1));
+        telephonyRxInMix.profiles.insert(telephonyRxInMix.profiles.begin(),
+                                         standardPcmAudioProfiles.begin(),
+                                         standardPcmAudioProfiles.end());
+        c.ports.push_back(telephonyRxInMix);
 
-        AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true,
-                                           createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
-                                                           AudioDeviceDescription::CONNECTION_USB));
-        c.ports.push_back(usbInDevice);
-        c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
+        AudioPort fmTunerInMix =
+                createPort(c.nextPortId++, "fm_tuner", 0, true, createPortMixExt(1, 1));
+        fmTunerInMix.profiles.insert(fmTunerInMix.profiles.begin(),
+                                     standardPcmAudioProfiles.begin(),
+                                     standardPcmAudioProfiles.end());
+        c.ports.push_back(fmTunerInMix);
 
-        c.routes.push_back(
-                createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, nullOutDevice.id));
-        c.routes.push_back(
-                createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, usbOutDevice.id));
-        c.routes.push_back(createRoute({loopOutMix.id}, loopOutDevice.id));
-        c.routes.push_back(createRoute({zeroInDevice.id, usbInDevice.id}, primaryInMix.id));
-        c.routes.push_back(createRoute({loopInDevice.id}, loopInMix.id));
+        c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, speakerOutDevice));
+        c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, usbOutDevice));
+        c.routes.push_back(createRoute({micInDevice, usbInDevice}, primaryInMix));
+        c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice));
+        c.routes.push_back(createRoute({telephonyRxInDevice}, telephonyRxInMix));
+        c.routes.push_back(createRoute({fmTunerInDevice}, fmTunerInMix));
 
         c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
+
+        MicrophoneInfo mic;
+        mic.id = "mic";
+        mic.device = micInDevice.ext.get<AudioPortExt::Tag::device>().device;
+        mic.group = 0;
+        mic.indexInTheGroup = 0;
+        c.microphones = std::vector<MicrophoneInfo>{mic};
+
         return c;
     }();
-    return configuration;
+    return std::make_unique<Configuration>(configuration);
+}
+
+// Remote Submix configuration:
+//
+// Device ports:
+//  * "Remote Submix Out", OUT_SUBMIX
+//    - profile PCM 24-bit; STEREO; 48000
+//  * "Remote Submix In", IN_SUBMIX
+//    - profile PCM 24-bit; STEREO; 48000
+//
+// Mix ports:
+//  * "r_submix output", stream count unlimited
+//    - profile PCM 24-bit; STEREO; 48000
+//  * "r_submix input", stream count unlimited
+//    - profile PCM 24-bit; STEREO; 48000
+//
+// Routes:
+//  "r_submix output" -> "Remote Submix Out"
+//  "Remote Submix In" -> "r_submix input"
+//
+std::unique_ptr<Configuration> getRSubmixConfiguration() {
+    static const Configuration configuration = []() {
+        Configuration c;
+
+        // Device ports
+
+        AudioPort rsubmixOutDevice = createPort(c.nextPortId++, "Remote Submix Out", 0, false,
+                                                createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
+        rsubmixOutDevice.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixOutDevice);
+
+        AudioPort rsubmixInDevice = createPort(c.nextPortId++, "Remote Submix In", 0, true,
+                                               createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
+        rsubmixInDevice.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixInDevice);
+
+        // Mix ports
+
+        AudioPort rsubmixOutMix =
+                createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(0, 0));
+        rsubmixOutMix.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixOutMix);
+
+        AudioPort rsubmixInMix =
+                createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(0, 0));
+        rsubmixInMix.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixInMix);
+
+        c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
+        c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInMix));
+
+        return c;
+    }();
+    return std::make_unique<Configuration>(configuration);
 }
 
 }  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
index 71b4b0e..5f17d71 100644
--- a/audio/aidl/default/EngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -20,7 +20,9 @@
 #include <functional>
 #include <unordered_map>
 
+#include <aidl/android/media/audio/common/AudioFlag.h>
 #include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
 
 #include "core-impl/EngineConfigXmlConverter.h"
 
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 971d946..86f0261 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -26,6 +26,7 @@
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 
 #include "core-impl/Module.h"
+#include "core-impl/SoundDose.h"
 #include "core-impl/Telephony.h"
 #include "core-impl/utils.h"
 
@@ -238,7 +239,14 @@
 
 internal::Configuration& Module::getConfig() {
     if (!mConfig) {
-        mConfig.reset(new internal::Configuration(internal::getNullPrimaryConfiguration()));
+        switch (mType) {
+            case Type::DEFAULT:
+                mConfig = std::move(internal::getPrimaryConfiguration());
+                break;
+            case Type::R_SUBMIX:
+                mConfig = std::move(internal::getRSubmixConfiguration());
+                break;
+        }
     }
     return *mConfig;
 }
@@ -924,4 +932,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) {
+    if (mSoundDose == nullptr) {
+        mSoundDose = ndk::SharedRefBase::make<SoundDose>();
+    }
+    *_aidl_return = mSoundDose;
+    LOG(DEBUG) << __func__ << ": returning instance of ISoundDose: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
new file mode 100644
index 0000000..3d222a8
--- /dev/null
+++ b/audio/aidl/default/SoundDose.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AHAL_SoundDose"
+
+#include "core-impl/SoundDose.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::audio::core {
+
+ndk::ScopedAStatus SoundDose::setOutputRs2(float in_rs2ValueDbA) {
+    if (in_rs2ValueDbA < MIN_RS2 || in_rs2ValueDbA > DEFAULT_MAX_RS2) {
+        LOG(ERROR) << __func__ << ": RS2 value is invalid: " << in_rs2ValueDbA;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    mRs2Value = in_rs2ValueDbA;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SoundDose::getOutputRs2(float* _aidl_return) {
+    *_aidl_return = mRs2Value;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SoundDose::registerSoundDoseCallback(
+        const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& in_callback) {
+    if (in_callback.get() == nullptr) {
+        LOG(ERROR) << __func__ << ": Callback is nullptr";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (mCallback != nullptr) {
+        LOG(ERROR) << __func__ << ": Sound dose callback was already registered";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    mCallback = in_callback;
+    LOG(DEBUG) << __func__ << ": Registered sound dose callback ";
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml
index bb4b01a..46b665f 100644
--- a/audio/aidl/default/android.hardware.audio.service-aidl.xml
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml
@@ -7,6 +7,11 @@
   <hal format="aidl">
     <name>android.hardware.audio.core</name>
     <version>1</version>
+    <fqname>IModule/r_submix</fqname>
+  </hal>
+  <hal format="aidl">
+    <name>android.hardware.audio.core</name>
+    <version>1</version>
     <fqname>IConfig/default</fqname>
   </hal>
 </manifest>
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index c0ffe70..ad79a0c 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -167,6 +167,7 @@
     method @NonNull public String getRawName();
     enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
     enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_PCM;
   }
 
   public enum AudioFormat {
@@ -280,6 +281,7 @@
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_ULTRASOUND;
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_BIT_PERFECT;
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
     enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index 2c18a1e..301c969 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -181,6 +181,7 @@
             <xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" />
             <xs:enumeration value="AUDIO_OUTPUT_FLAG_SPATIALIZER" />
             <xs:enumeration value="AUDIO_OUTPUT_FLAG_ULTRASOUND" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_BIT_PERFECT" />
             <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
             <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
             <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
@@ -575,6 +576,7 @@
         <xs:restriction base="xs:string">
             <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_NONE"/>
             <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_IEC61937"/>
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_PCM"/>
         </xs:restriction>
     </xs:simpleType>
     <xs:complexType name="profile">
diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h
index 95adcd7..3b4c494 100644
--- a/audio/aidl/default/include/core-impl/Configuration.h
+++ b/audio/aidl/default/include/core-impl/Configuration.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <map>
+#include <memory>
 #include <vector>
 
 #include <aidl/android/hardware/audio/core/AudioPatch.h>
@@ -41,6 +42,7 @@
     int32_t nextPatchId = 1;
 };
 
-Configuration& getNullPrimaryConfiguration();
+std::unique_ptr<Configuration> getPrimaryConfiguration();
+std::unique_ptr<Configuration> getRSubmixConfiguration();
 
 }  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 3509327..3cc31c5 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -31,6 +31,9 @@
   public:
     // This value is used for all AudioPatches and reported by all streams.
     static constexpr int32_t kLatencyMs = 10;
+    enum Type : int { DEFAULT, R_SUBMIX };
+
+    explicit Module(Type type) : mType(type) {}
 
   private:
     ndk::ScopedAStatus setModuleDebug(
@@ -83,6 +86,7 @@
     ndk::ScopedAStatus updateScreenRotation(
             ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
     ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
+    ndk::ScopedAStatus getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) override;
 
     void cleanUpPatch(int32_t patchId);
     ndk::ScopedAStatus createStreamContext(
@@ -105,6 +109,7 @@
     // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes;
     static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30;
 
+    const Type mType;
     std::unique_ptr<internal::Configuration> mConfig;
     ModuleDebug mDebug;
     // Since it is required to return the same instance of the ITelephony, even
@@ -119,6 +124,7 @@
     bool mMasterMute = false;
     float mMasterVolume = 1.0f;
     bool mMicMute = false;
+    std::shared_ptr<ISoundDose> mSoundDose;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
new file mode 100644
index 0000000..54a6cbf
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -0,0 +1,42 @@
+/*
+ * 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 <mutex>
+
+#include <aidl/android/hardware/audio/core/BnSoundDose.h>
+#include <aidl/android/media/audio/common/AudioDevice.h>
+
+using aidl::android::media::audio::common::AudioDevice;
+
+namespace aidl::android::hardware::audio::core {
+
+class SoundDose : public BnSoundDose {
+  public:
+    SoundDose() : mRs2Value(DEFAULT_MAX_RS2){};
+
+    ndk::ScopedAStatus setOutputRs2(float in_rs2ValueDbA) override;
+    ndk::ScopedAStatus getOutputRs2(float* _aidl_return) override;
+    ndk::ScopedAStatus registerSoundDoseCallback(
+            const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& in_callback) override;
+
+  private:
+    std::shared_ptr<ISoundDose::IHalSoundDoseCallback> mCallback;
+    float mRs2Value;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 48067a2..b11af4e 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -43,14 +43,21 @@
             AServiceManager_addService(config->asBinder().get(), configName.c_str());
     CHECK_EQ(STATUS_OK, status);
 
-    // Make the default module
-    auto moduleDefault = ndk::SharedRefBase::make<Module>();
+    // Make modules
+    auto moduleDefault = ndk::SharedRefBase::make<Module>(Module::Type::DEFAULT);
+    const std::string moduleDefaultName = std::string() + Module::descriptor + "/default";
     AIBinder_setMinSchedulerPolicy(moduleDefault->asBinder().get(), SCHED_NORMAL,
                                    ANDROID_PRIORITY_AUDIO);
-    const std::string moduleDefaultName = std::string() + Module::descriptor + "/default";
     status = AServiceManager_addService(moduleDefault->asBinder().get(), moduleDefaultName.c_str());
     CHECK_EQ(STATUS_OK, status);
 
+    auto moduleRSubmix = ndk::SharedRefBase::make<Module>(Module::Type::R_SUBMIX);
+    const std::string moduleRSubmixName = std::string() + Module::descriptor + "/r_submix";
+    AIBinder_setMinSchedulerPolicy(moduleRSubmix->asBinder().get(), SCHED_NORMAL,
+                                   ANDROID_PRIORITY_AUDIO);
+    status = AServiceManager_addService(moduleRSubmix->asBinder().get(), moduleRSubmixName.c_str());
+    CHECK_EQ(STATUS_OK, status);
+
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
 }
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index bf73648..e7f5817 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -10,6 +10,8 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/core/IConfig.h>
+#include <aidl/android/media/audio/common/AudioFlag.h>
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
 
 #include "AudioHalBinderServiceUtil.h"
 #include "TestUtils.h"
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index eb7a3e4..5dadea3 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -36,6 +36,7 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/core/BnStreamCallback.h>
 #include <aidl/android/hardware/audio/core/IModule.h>
+#include <aidl/android/hardware/audio/core/ISoundDose.h>
 #include <aidl/android/hardware/audio/core/ITelephony.h>
 #include <aidl/android/media/audio/common/AudioIoFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
@@ -56,6 +57,7 @@
 using aidl::android::hardware::audio::core::AudioPatch;
 using aidl::android::hardware::audio::core::AudioRoute;
 using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::ISoundDose;
 using aidl::android::hardware::audio::core::IStreamIn;
 using aidl::android::hardware::audio::core::IStreamOut;
 using aidl::android::hardware::audio::core::ITelephony;
@@ -79,6 +81,7 @@
 using aidl::android::media::audio::common::AudioUsage;
 using aidl::android::media::audio::common::Void;
 using android::hardware::audio::common::isBitPositionFlagSet;
+using android::hardware::audio::common::isTelephonyDeviceType;
 using android::hardware::audio::common::StreamLogic;
 using android::hardware::audio::common::StreamWorker;
 using ndk::enum_range;
@@ -2220,9 +2223,9 @@
         }
     }
 
-    bool ValidateObservablePosition(const AudioPortConfig& /*portConfig*/) {
-        // May return false based on the portConfig, e.g. for telephony ports.
-        return true;
+    bool ValidateObservablePosition(const AudioPortConfig& devicePortConfig) {
+        return !isTelephonyDeviceType(
+                devicePortConfig.ext.get<AudioPortExt::Tag::device>().device.type.type);
     }
 
     // Set up a patch first, then open a stream.
@@ -2247,7 +2250,7 @@
         worker.join();
         EXPECT_FALSE(worker.hasError()) << worker.getError();
         EXPECT_EQ("", driver.getUnexpectedStateTransition());
-        if (ValidateObservablePosition(portConfig)) {
+        if (ValidateObservablePosition(devicePortConfig)) {
             EXPECT_TRUE(driver.hasObservablePositionIncrease());
             EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
         }
@@ -2275,7 +2278,7 @@
         worker.join();
         EXPECT_FALSE(worker.hasError()) << worker.getError();
         EXPECT_EQ("", driver.getUnexpectedStateTransition());
-        if (ValidateObservablePosition(portConfig)) {
+        if (ValidateObservablePosition(devicePortConfig)) {
             EXPECT_TRUE(driver.hasObservablePositionIncrease());
             EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
         }
@@ -2467,6 +2470,92 @@
     }
 }
 
+class AudioCoreSoundDose : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    class NoOpHalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
+      public:
+        ndk::ScopedAStatus onMomentaryExposureWarning(float in_currentDbA,
+                                                      const AudioDevice& in_audioDevice) override;
+        ndk::ScopedAStatus onNewMelValues(
+                const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
+                const AudioDevice& in_audioDevice) override;
+    };
+
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getSoundDose(&soundDose));
+        callback = ndk::SharedRefBase::make<NoOpHalSoundDoseCallback>();
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<ISoundDose> soundDose;
+    std::shared_ptr<ISoundDose::IHalSoundDoseCallback> callback;
+};
+
+ndk::ScopedAStatus AudioCoreSoundDose::NoOpHalSoundDoseCallback::onMomentaryExposureWarning(
+        float in_currentDbA, const AudioDevice& in_audioDevice) {
+    // Do nothing
+    (void)in_currentDbA;
+    (void)in_audioDevice;
+    LOG(INFO) << "NoOpHalSoundDoseCallback::onMomentaryExposureWarning called";
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioCoreSoundDose::NoOpHalSoundDoseCallback::onNewMelValues(
+        const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
+        const AudioDevice& in_audioDevice) {
+    // Do nothing
+    (void)in_melRecord;
+    (void)in_audioDevice;
+    LOG(INFO) << "NoOpHalSoundDoseCallback::onNewMelValues called";
+
+    return ndk::ScopedAStatus::ok();
+}
+
+TEST_P(AudioCoreSoundDose, GetSetOutputRs2) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(soundDose.get(), &ISoundDose::getOutputRs2,
+                                                 &ISoundDose::setOutputRs2,
+                                                 /*validValues=*/{80.f, 90.f, 100.f},
+                                                 /*invalidValues=*/{79.f, 101.f}, &isSupported));
+    EXPECT_TRUE(isSupported) << "Getting/Setting RS2 must be supported";
+}
+
+TEST_P(AudioCoreSoundDose, CheckDefaultRs2Value) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    float rs2Value;
+    ASSERT_IS_OK(soundDose->getOutputRs2(&rs2Value));
+    EXPECT_EQ(rs2Value, ISoundDose::DEFAULT_MAX_RS2);
+}
+
+TEST_P(AudioCoreSoundDose, RegisterSoundDoseCallbackTwiceThrowsException) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    ASSERT_IS_OK(soundDose->registerSoundDoseCallback(callback));
+    EXPECT_STATUS(EX_ILLEGAL_STATE, soundDose->registerSoundDoseCallback(callback))
+            << "Registering sound dose callback twice should throw EX_ILLEGAL_STATE";
+}
+
+TEST_P(AudioCoreSoundDose, RegisterSoundDoseNullCallbackThrowsException) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, soundDose->registerSoundDoseCallback(nullptr))
+            << "Registering nullptr sound dose callback should throw EX_ILLEGAL_ARGUMENT";
+}
+
 INSTANTIATE_TEST_SUITE_P(AudioCoreModuleTest, AudioCoreModule,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
@@ -2483,6 +2572,10 @@
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamOut);
+INSTANTIATE_TEST_SUITE_P(AudioCoreSoundDoseTest, AudioCoreSoundDose,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreSoundDose);
 
 // This is the value used in test sequences for which the test needs to ensure
 // that the HAL stays in a transient state long enough to receive the next command.
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
index 07edae8..3464412 100644
--- a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
@@ -40,5 +40,6 @@
   INVALID_STATE = 3,
   NOT_SUPPORTED = 4,
   TIMEOUT = 5,
-  UNKNOWN_ERROR = 6,
+  CANCELED = 6,
+  UNKNOWN_ERROR = 7,
 }
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
index 1f0221c..8de12c8 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
@@ -36,6 +36,7 @@
      * @param result {@link Result#TIMEOUT} in case that tune(), seek() or
      *               step() is not completed within
      *               @link IBroadcastRadio#TUNER_TIMEOUT_MS}
+     *               or {@link Result#CANCELED} if the command was canceled.
      * @param selector A ProgramSelector structure passed from tune() call;
      *                 empty for step() and seek().
      */
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
index 9985ccb..3f7ddac 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
@@ -55,6 +55,12 @@
     TIMEOUT,
 
     /**
+     * Error used when a tune, seek, step or operation is canceled before
+     * being processed.
+     */
+    CANCELED,
+
+    /**
      * Error that does not follow into the error categories above.
      */
     UNKNOWN_ERROR,
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 0209a0e..42e550e 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -238,7 +238,8 @@
         }
         callback->onCurrentProgramInfoChanged(programInfo);
     };
-    mThread->schedule(task, kTuneDelayTimeMs);
+    auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
+    mThread->schedule(task, cancelTask, kTuneDelayTimeMs);
 
     return ScopedAStatus::ok();
 }
@@ -258,6 +259,7 @@
 
     const auto& list = mVirtualRadio.getProgramList();
     std::shared_ptr<ITunerCallback> callback = mCallback;
+    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
     if (list.empty()) {
         mIsTuneCompleted = false;
         auto task = [callback]() {
@@ -265,7 +267,7 @@
 
             callback->onTuneFailed(Result::TIMEOUT, {});
         };
-        mThread->schedule(task, kSeekDelayTimeMs);
+        mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
 
         return ScopedAStatus::ok();
     }
@@ -298,7 +300,7 @@
         }
         callback->onCurrentProgramInfoChanged(programInfo);
     };
-    mThread->schedule(task, kSeekDelayTimeMs);
+    mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
 
     return ScopedAStatus::ok();
 }
@@ -352,7 +354,8 @@
         }
         callback->onCurrentProgramInfoChanged(programInfo);
     };
-    mThread->schedule(task, kStepDelayTimeMs);
+    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
+    mThread->schedule(task, cancelTask, kStepDelayTimeMs);
 
     return ScopedAStatus::ok();
 }
diff --git a/broadcastradio/common/utils/WorkerThread.cpp b/broadcastradio/common/utils/WorkerThread.cpp
index dd87f53..43fd04a 100644
--- a/broadcastradio/common/utils/WorkerThread.cpp
+++ b/broadcastradio/common/utils/WorkerThread.cpp
@@ -18,14 +18,13 @@
 
 namespace android {
 
-using std::chrono::milliseconds;
-using std::chrono::steady_clock;
 using std::function;
 using std::lock_guard;
 using std::mutex;
-using std::priority_queue;
-using std::this_thread::sleep_for;
 using std::unique_lock;
+using std::chrono::milliseconds;
+using std::chrono::steady_clock;
+using std::this_thread::sleep_for;
 
 bool operator<(const WorkerThread::Task& lhs, const WorkerThread::Task& rhs) {
     return lhs.when > rhs.when;
@@ -47,16 +46,26 @@
 }
 
 void WorkerThread::schedule(function<void()> task, milliseconds delay) {
+    auto cancelTask = []() {};
+    schedule(std::move(task), cancelTask, delay);
+}
+
+void WorkerThread::schedule(function<void()> task, function<void()> cancelTask,
+                            milliseconds delay) {
     auto when = steady_clock::now() + delay;
 
     lock_guard<mutex> lk(mMut);
-    mTasks.push(Task({when, task}));
+    mTasks.push(Task({when, std::move(task), std::move(cancelTask)}));
     mCond.notify_one();
 }
 
 void WorkerThread::cancelAll() {
     lock_guard<mutex> lk(mMut);
-    priority_queue<Task>().swap(mTasks);  // empty queue
+    while (!mTasks.empty()) {
+        auto task = mTasks.top();
+        task.onCanceled();
+        mTasks.pop();
+    }
 }
 
 void WorkerThread::threadLoop() {
diff --git a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
index 62bede6..457b57e 100644
--- a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
+++ b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
@@ -28,12 +28,15 @@
     virtual ~WorkerThread();
 
     void schedule(std::function<void()> task, std::chrono::milliseconds delay);
+    void schedule(std::function<void()> task, std::function<void()> cancelTask,
+                  std::chrono::milliseconds delay);
     void cancelAll();
 
    private:
     struct Task {
         std::chrono::time_point<std::chrono::steady_clock> when;
         std::function<void()> what;
+        std::function<void()> onCanceled;
     };
     friend bool operator<(const Task& lhs, const Task& rhs);
 
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 4a5c8de..a907f20 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -31,6 +31,13 @@
         <interface>
             <name>IModule</name>
             <instance>default</instance>
+            <instance>a2dp</instance>
+            <instance>bluetooth</instance>
+            <instance>hearing_aid</instance>
+            <instance>msd</instance>
+            <instance>r_submix</instance>
+            <instance>stub</instance>
+            <instance>usb</instance>
         </interface>
         <interface>
             <name>IConfig</name>
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 478e2b7..d11592f 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -29,6 +29,7 @@
         "android.hardware.graphics.allocator-ndk_static",
         "android.hardware.graphics.composer3-ndk_static",
         "hidl_defaults",
+        "librenderengine_deps",
     ],
     srcs: [
         "ComposerVts.cpp",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index c693d35..3476376 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -29,8 +29,7 @@
         "VtsHalTargetTestDefaults",
         "android.hardware.graphics.allocator-ndk_static",
         "android.hardware.graphics.composer3-ndk_static",
-        // Needed for librenderengine
-        "skia_deps",
+        "librenderengine_deps",
     ],
     tidy_timeout_srcs: [
         "VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index cbd2da5..88b5de4 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -28,8 +28,7 @@
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
-        // Needed for librenderengine
-        "skia_deps",
+        "librenderengine_deps",
         "android.hardware.graphics.common-ndk_static",
         "android.hardware.graphics.composer3-ndk_static",
     ],
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index da894cd..c264dfd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -38,5 +38,5 @@
   String atr;
   String eid;
   android.hardware.radio.config.SimPortInfo[] portInfo;
-  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
index 9000d43..46cb7be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
@@ -44,6 +44,7 @@
   String iccid;
   String eid;
   android.hardware.radio.config.SlotPortMapping slotMap;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
   const int STATE_ABSENT = 0;
   const int STATE_PRESENT = 1;
   const int STATE_ERROR = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index 2f2e07b..c391e5a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -41,5 +41,5 @@
   int p2;
   int p3;
   String data;
-  boolean isEs10;
+  boolean isEs10 = false;
 }
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 73f2954..6a36d5e 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -54,7 +54,8 @@
      */
     SimPortInfo[] portInfo;
     /**
-     * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0
+     * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0. Should always
+     * report proper MEP mode irrespective of whether the slot is active or inactive.
      */
-    MultipleEnabledProfilesMode supportedMepMode;
+    MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index a14cf7d..1419c51 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.radio.sim;
 
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
 import android.hardware.radio.config.SlotPortMapping;
 import android.hardware.radio.sim.AppStatus;
 import android.hardware.radio.sim.PinState;
@@ -93,4 +94,8 @@
      * PortId is the id (enumerated value) for the associated port available on the SIM.
      */
     SlotPortMapping slotMap;
+    /**
+     * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0
+     */
+    MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index 4759e2e..9799f2b 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -53,5 +53,5 @@
      * isEs10 indicates that the current streaming APDU contains an ES10 command or it is a regular
      * APDU. (As per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A1)
      */
-    boolean isEs10;
+    boolean isEs10 = false;
 }
diff --git a/security/keymint/aidl/default/android.hardware.hardware_keystore.xml b/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
index 2ebf1fe..4c75596 100644
--- a/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
+++ b/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <permissions>
-  <feature name="android.hardware.hardware_keystore" version="200" />
+  <feature name="android.hardware.hardware_keystore" version="300" />
 </permissions>
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 13143bf..e7f5a0f 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -90,24 +90,3 @@
         "libgmock_ndk",
     ],
 }
-
-cc_test {
-    name: "VtsHalRemotelyProvisionedComponentTargetTest",
-    defaults: [
-        "keymint_vts_defaults",
-    ],
-    srcs: [
-        "VtsRemotelyProvisionedComponentTests.cpp",
-    ],
-    static_libs: [
-        "libgmock_ndk",
-        "libkeymaster_portable",
-        "libkeymint_vts_test_utils",
-        "libpuresoftkeymasterdevice",
-    ],
-    test_config: "VtsRemotelyProvisionedComponentTests.xml",
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-}
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index b8d0c20..5a86283 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1027,7 +1027,7 @@
  * without providing NOT_BEFORE and NOT_AFTER parameters.
  */
 TEST_P(NewKeyGenerationTest, RsaWithMissingValidity) {
-    if (AidlVersion() < 2) {
+    if (AidlVersion() < 3) {
         /*
          * The KeyMint V1 spec required that CERTIFICATE_NOT_{BEFORE,AFTER} be
          * specified for asymmetric key generation. However, this was not
@@ -1130,16 +1130,16 @@
 }
 
 /*
- * NewKeyGenerationTest.RsaWithRpkAttestation
+ * NewKeyGenerationTest.RsaWithRkpAttestation
  *
- * Verifies that keymint can generate all required RSA key sizes, using an attestation key
+ * Verifies that keymint can generate all required RSA key sizes using an attestation key
  * that has been generated using an associate IRemotelyProvisionedComponent.
- *
- * This test is disabled because the KeyMint specification does not require that implementations
- * of the first version of KeyMint have to also implement IRemotelyProvisionedComponent.
- * However, the test is kept in the code because KeyMint v2 will impose this requirement.
  */
-TEST_P(NewKeyGenerationTest, DISABLED_RsaWithRpkAttestation) {
+TEST_P(NewKeyGenerationTest, RsaWithRkpAttestation) {
+    if (AidlVersion() < 2) {
+        GTEST_SKIP() << "Only required starting with KeyMint v2";
+    }
+
     // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
     // instance.
     std::shared_ptr<IRemotelyProvisionedComponent> rp;
@@ -1208,6 +1208,81 @@
 }
 
 /*
+ * NewKeyGenerationTest.EcdsaWithRkpAttestation
+ *
+ * Verifies that keymint can generate all required ECDSA key sizes using an attestation key
+ * that has been generated using an associate IRemotelyProvisionedComponent.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
+    if (AidlVersion() < 2) {
+        GTEST_SKIP() << "Only required starting with KeyMint v2";
+    }
+
+    // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
+    // instance.
+    std::shared_ptr<IRemotelyProvisionedComponent> rp;
+    ASSERT_TRUE(matching_rp_instance(GetParam(), &rp))
+            << "No IRemotelyProvisionedComponent found that matches KeyMint device " << GetParam();
+
+    // Generate a P-256 keypair to use as an attestation key.
+    MacedPublicKey macedPubKey;
+    std::vector<uint8_t> privateKeyBlob;
+    auto status =
+            rp->generateEcdsaP256KeyPair(/* testMode= */ false, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(status.isOk());
+    vector<uint8_t> coseKeyData;
+    check_maced_pubkey(macedPubKey, /* testMode= */ false, &coseKeyData);
+
+    AttestationKey attestation_key;
+    attestation_key.keyBlob = std::move(privateKeyBlob);
+    attestation_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+    for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
+        auto challenge = "hello";
+        auto app_id = "foo";
+
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK,
+                  GenerateKey(AuthorizationSetBuilder()
+                                      .EcdsaSigningKey(curve)
+                                      .Digest(Digest::NONE)
+                                      .AttestationChallenge(challenge)
+                                      .AttestationApplicationId(app_id)
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .SetDefaultValidity(),
+                              attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
+
+        // Attestation by itself is not valid (last entry is not self-signed).
+        EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_));
+
+        // The signature over the attested key should correspond to the P256 public key.
+        ASSERT_GT(cert_chain_.size(), 0);
+        X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+        ASSERT_TRUE(key_cert.get());
+        EVP_PKEY_Ptr signing_pubkey;
+        p256_pub_key(coseKeyData, &signing_pubkey);
+        ASSERT_TRUE(signing_pubkey.get());
+
+        ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
+                << "Verification of attested certificate failed "
+                << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.RsaEncryptionWithAttestation
  *
  * Verifies that keymint attestation for RSA encryption keys with challenge and
diff --git a/security/rkp/OWNERS b/security/rkp/OWNERS
new file mode 100644
index 0000000..d25977f
--- /dev/null
+++ b/security/rkp/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1084908
+
+jbires@google.com
+sethmo@google.com
+trong@google.com
diff --git a/security/rkp/TEST_MAPPING b/security/rkp/TEST_MAPPING
new file mode 100644
index 0000000..9ce5e9b
--- /dev/null
+++ b/security/rkp/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalRemotelyProvisionedComponentTargetTest"
+    }
+  ]
+}
diff --git a/security/rkp/aidl/vts/functional/Android.bp b/security/rkp/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..9c2b6e1
--- /dev/null
+++ b/security/rkp/aidl/vts/functional/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2020 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalRemotelyProvisionedComponentTargetTest",
+    defaults: [
+        "keymint_vts_defaults",
+    ],
+    srcs: [
+        "VtsRemotelyProvisionedComponentTests.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcrypto",
+    ],
+    static_libs: [
+        "libcppbor_external",
+        "libgmock_ndk",
+        "libkeymint_vts_test_utils",
+    ],
+    test_config: "VtsRemotelyProvisionedComponentTests.xml",
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/rkp/aidl/vts/functional/AndroidTest.xml
similarity index 100%
copy from security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
copy to security/rkp/aidl/vts/functional/AndroidTest.xml
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
similarity index 99%
rename from security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
rename to security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 6d9c8c9..cb1c692 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -18,7 +18,7 @@
 #include <string>
 #define LOG_TAG "VtsRemotelyProvisionableComponentTests"
 
-#include <AndroidRemotelyProvisionedComponentDevice.h>
+#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 #include <aidl/android/hardware/security/keymint/SecurityLevel.h>
 #include <android/binder_manager.h>
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
similarity index 100%
rename from security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
rename to security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index 31a17db..305383e 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -351,7 +351,7 @@
     return Return<void>();
 }
 
-Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /*args*/) {
+Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
     if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
         ALOGE("%s: missing fd for writing", __FUNCTION__);
         return Void();
@@ -385,7 +385,7 @@
         stream << "  Name: " << subHal->getName() << std::endl;
         stream << "  Debug dump: " << std::endl;
         android::base::WriteStringToFd(stream.str(), writeFd);
-        subHal->debug(fd, {});
+        subHal->debug(fd, args);
         stream.str("");
         stream << std::endl;
     }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 53d5770..3740a10 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -95,4 +95,5 @@
   void stopDppInitiator();
   void stopDppResponder(in int ownBootstrapId);
   void stopRxFilter();
+  android.hardware.wifi.supplicant.SignalPollResult[] getSignalPollResults();
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 45563b3..b54f04d 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -60,16 +60,20 @@
   oneway void onNetworkNotFound(in byte[] ssid);
   oneway void onNetworkRemoved(in int id);
   oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+  /**
+   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onSupplicantStateChanged()
+   */
   oneway void onStateChanged(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent);
   oneway void onWpsEventFail(in byte[] bssid, in android.hardware.wifi.supplicant.WpsConfigError configError, in android.hardware.wifi.supplicant.WpsErrorIndication errorInd);
   oneway void onWpsEventPbcOverlap();
   oneway void onWpsEventSuccess();
   oneway void onQosPolicyReset();
   oneway void onQosPolicyRequest(in int qosPolicyRequestId, in android.hardware.wifi.supplicant.QosPolicyData[] qosPolicyData);
-  oneway void onStateChangedWithAkm(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent, in android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask);
   oneway void onMloLinksInfoChanged(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.MloLinkInfoChangeReason reason);
   oneway void onDppConfigReceived(in android.hardware.wifi.supplicant.DppConfigurationData configData);
   oneway void onDppConnectionStatusResultSent(in android.hardware.wifi.supplicant.DppStatusErrorCode code);
+  oneway void onBssFrequencyChanged(in int frequencyMhz);
+  oneway void onSupplicantStateChanged(in android.hardware.wifi.supplicant.SupplicantStateChangeData stateChangeData);
   @Backing(type="int") @VintfStability
   enum MloLinkInfoChangeReason {
     TID_TO_LINK_MAP = 0,
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..52d3f24
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable SignalPollResult {
+  int linkId;
+  int currentRssiDbm;
+  int txBitrateMbps;
+  int rxBitrateMbps;
+  int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..e6bb859
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable SupplicantStateChangeData {
+  android.hardware.wifi.supplicant.StaIfaceCallbackState newState;
+  int id;
+  byte[] ssid;
+  byte[] bssid;
+  android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask;
+  int frequencyMhz;
+  boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 9edf210..9ceb3c0 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -31,6 +31,7 @@
 import android.hardware.wifi.supplicant.MloLinksInfo;
 import android.hardware.wifi.supplicant.QosPolicyStatus;
 import android.hardware.wifi.supplicant.RxFilterType;
+import android.hardware.wifi.supplicant.SignalPollResult;
 import android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
 
@@ -781,4 +782,15 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
     void stopRxFilter();
+
+    /**
+     * This method returns the signal poll results. Results will be for each
+     * link in case of Multiple Link Operation (MLO).
+     *
+     * @return Signal Poll Results per link.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    SignalPollResult[] getSignalPollResults();
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 29bb0f9..5001800 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -29,11 +29,11 @@
 import android.hardware.wifi.supplicant.DppProgressCode;
 import android.hardware.wifi.supplicant.DppStatusErrorCode;
 import android.hardware.wifi.supplicant.Hs20AnqpData;
-import android.hardware.wifi.supplicant.KeyMgmtMask;
 import android.hardware.wifi.supplicant.OsuMethod;
 import android.hardware.wifi.supplicant.QosPolicyData;
 import android.hardware.wifi.supplicant.StaIfaceCallbackState;
 import android.hardware.wifi.supplicant.StaIfaceReasonCode;
+import android.hardware.wifi.supplicant.SupplicantStateChangeData;
 import android.hardware.wifi.supplicant.WpsConfigError;
 import android.hardware.wifi.supplicant.WpsErrorIndication;
 
@@ -259,7 +259,8 @@
      * |ssid|, |bssid| parameters must indicate the parameters of the network/AP
      * which caused this state transition.
      * <p>
-     * This callback is deprecated from AIDL v2, newer HAL should call onStateChangedWithAkm().
+     * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+     * onSupplicantStateChanged()
      *
      * @param newState New State of the interface. This must be one of the |State|
      *        values above.
@@ -313,29 +314,6 @@
     void onQosPolicyRequest(in int qosPolicyRequestId, in QosPolicyData[] qosPolicyData);
 
     /**
-     * Used to indicate a state change event on this particular iface. If this
-     * event is triggered by a particular network, the |id|,
-     * |ssid|, |bssid| parameters must indicate the parameters of the network/AP
-     * which caused this state transition.
-     *
-     * @param newState New State of the interface. This must be one of the
-     *        |StaIfaceCallbackState| values above.
-     * @param bssid BSSID of the corresponding AP which caused this state
-     *        change event. This must be zero'ed if this event is not
-     *        specific to a particular network.
-     * @param id ID of the corresponding network which caused this
-     *        state change event. This must be invalid (-1) if this
-     *        event is not specific to a particular network.
-     * @param ssid SSID of the corresponding network which caused this state
-     *        change event. This must be empty if this event is not specific
-     *        to a particular network.
-     * @param filsHlpSent Whether FILS HLP IEs were included in this association.
-     * @param keyMgmtMask current used key mgmt mask.
-     */
-    void onStateChangedWithAkm(in StaIfaceCallbackState newState, in byte[] bssid, in int id,
-            in byte[] ssid, in boolean filsHlpSent, in KeyMgmtMask keyMgmtMask);
-
-    /**
      * Reason codes to be used with the callback |ISupplicantStaIfaceCallback.onMloLinksInfoChanged|
      */
     @VintfStability
@@ -384,4 +362,20 @@
      * Indicates that DPP connection status result frame is sent.
      */
     void onDppConnectionStatusResultSent(in DppStatusErrorCode code);
+
+    /**
+     * Used to indicate that the operating frequency has changed for this BSS.
+     * This event is triggered when STA switches the channel due to channel
+     * switch announcement from the connected access point.
+     *
+     * @param frequencyMhz New operating frequency in MHz.
+     */
+    void onBssFrequencyChanged(in int frequencyMhz);
+
+    /**
+     * Used to indicate a state change event on this particular iface.
+     *
+     * @param stateChangeData Supplicant state change related information.
+     */
+    void onSupplicantStateChanged(in SupplicantStateChangeData stateChangeData);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..a3b11a0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Signal polling results.
+ */
+@VintfStability
+parcelable SignalPollResult {
+    /**
+     * Link identifier.
+     */
+    int linkId;
+    /**
+     * RSSI value in dBM.
+     */
+    int currentRssiDbm;
+    /**
+     * Last transmitted packet bit rate in Mbps.
+     */
+    int txBitrateMbps;
+    /**
+     * Last received packet bit rate in Mbps.
+     */
+    int rxBitrateMbps;
+    /**
+     * Frequency in MHz.
+     */
+    int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..8fa5dc7
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.hardware.wifi.supplicant.StaIfaceCallbackState;
+
+/**
+ * Supplicant state change related information.
+ */
+@VintfStability
+parcelable SupplicantStateChangeData {
+    /**
+     * New State of the interface. This must be one of the
+     * |StaIfaceCallbackState| values.
+     */
+    StaIfaceCallbackState newState;
+    /**
+     * ID of the corresponding network which caused this
+     * state change event. This must be invalid (-1) if this
+     * event is not specific to a particular network.
+     */
+    int id;
+    /**
+     * SSID of the corresponding network which caused this state
+     * change event. This must be empty if this event is not specific
+     * to a particular network.
+     */
+    byte[] ssid;
+    /**
+     * BSSID of the corresponding AP which caused this state
+     * change event. This must be zero'ed if this event is not
+     * specific to a particular network.
+     */
+    byte[/* 6 */] bssid;
+
+    /**
+     * Currently used key mgmt mask.
+     */
+    KeyMgmtMask keyMgmtMask;
+    /*
+     * Frequency of the connected channel in MHz. This must be zero if this
+     * event is not specific to a particular network.
+     */
+    int frequencyMhz;
+    /*
+     * Flag to indicate that FILS HLP IEs were included in this association.
+     * This flag is valid only for WPA_COMPLETED state change.
+     */
+    boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index cb2881b..d536618 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -206,11 +206,9 @@
                                       QosPolicyData /* qosPolicyData */>&) override {
         return ndk::ScopedAStatus::ok();
     }
-    ::ndk::ScopedAStatus onStateChangedWithAkm(
-            ::aidl::android::hardware::wifi::supplicant::StaIfaceCallbackState /* newState */,
-            const std::vector<uint8_t>& /* bssid */, int32_t /* id */,
-            const std::vector<uint8_t>& /* ssid */, bool /* filsHlpSent */,
-            ::aidl::android::hardware::wifi::supplicant::KeyMgmtMask /* keyMgmtMask*/) override {
+    ::ndk::ScopedAStatus onSupplicantStateChanged(
+            const ::aidl::android::hardware::wifi::supplicant::
+                    SupplicantStateChangeData& /* stateChangeData */) override {
         return ndk::ScopedAStatus::ok();
     }
     ::ndk::ScopedAStatus onMloLinksInfoChanged(
@@ -227,6 +225,9 @@
             ::aidl::android::hardware::wifi::supplicant::DppStatusErrorCode /* code */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onBssFrequencyChanged(int32_t /* frequencyMhz */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantStaIfaceAidlTest : public testing::TestWithParam<std::string> {