Merge "Implement getPropConfigs in Default VHAL."
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 898c22d..89585b0 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -90,6 +90,7 @@
         },
         {
             "Bluetooth Audio API",
+            "android.hardware.bluetooth.audio@2.2::IBluetoothAudioProvidersFactory",
             "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory",
             "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory",
         },
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
index d2ba339..8c92cbd 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -102,6 +102,9 @@
             if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
             auto [flags, isOffload] = generateOutFlags(mixPort);
             for (const auto& profile : mixPort.getProfile()) {
+                if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+                    !profile.hasChannelMasks())
+                    continue;
                 auto configs = combineAudioConfig(profile.getChannelMasks(),
                                                   profile.getSamplingRates(), profile.getFormat());
                 for (auto& config : configs) {
@@ -231,6 +234,9 @@
                                std::back_inserter(flags), [](auto flag) { return toString(flag); });
             }
             for (const auto& profile : mixPort.getProfile()) {
+                if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+                    !profile.hasChannelMasks())
+                    continue;
                 auto configs = combineAudioConfig(profile.getChannelMasks(),
                                                   profile.getSamplingRates(), profile.getFormat());
                 for (const auto& config : configs) {
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 7c25c23..b99ed43 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -245,6 +245,7 @@
     data: [
         "tests/apm_config_no_vx_7_0.xml",
         "tests/apm_config_with_vx_7_0.xml",
+        "tests/apm_config_b_204314749_7_0.xml",
     ],
     test_config: "tests/HalAudioV7_0GeneratorTest.xml",
 }
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
index 2e79455..3dc5b33 100644
--- a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
@@ -24,6 +24,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
         <option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
+        <option name="push" value="apm_config_b_204314749_7_0.xml->/data/local/tmp/apm_config_b_204314749_7_0.xml" />
         <option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
     </target_preparer>
 
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_b_204314749_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_b_204314749_7_0.xml
new file mode 100644
index 0000000..5bdca9a
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_b_204314749_7_0.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g. version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="false"/>
+
+
+    <!-- Modules section:
+        There is one section per audio HW module present on the platform.
+        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+        The module names are the same as in current .conf file:
+                “primary”, “A2DP”, “remote_submix”, “USB”
+        Each module will contain the following sections:
+        “devicePorts”: a list of device descriptors for all input and output devices accessible via this
+        module.
+        This contains both permanently attached devices and removable devices.
+        “mixPorts”: listing all output and input streams exposed by the audio HAL
+        “routes”: list of possible connections between input and output devices or between stream and
+        devices.
+            "route": is defined by an attribute:
+                -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
+                -"sink": the sink involved in this route
+                -"sources": all the sources than can be connected to the sink via vis route
+        “attachedDevices”: permanently attached devices.
+        The attachedDevices section is a list of devices names. The names correspond to device names
+        defined in <devicePorts> section.
+        “defaultOutputDevice”: device to be used by default when no policy rule applies
+    -->
+    <modules>
+        <!-- Primary Audio HAL -->
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+                <item>Built-In Back Mic</item>
+                <item>Echo Reference</item>
+                <item>Tuner</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="tunnel pcm" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_HW_AV_SYNC">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="32000 44100 48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="direct pcm" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="32000 44100 48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="direct output" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name=""/>
+                </mixPort>
+                <mixPort name="tunnel direct output" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_HW_AV_SYNC">
+                    <profile name=""/>
+                </mixPort>
+                <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                            samplingRates="48000"
+                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+                <mixPort name="tunnel a2dp" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_HW_AV_SYNC">
+                    <profile name=""/>
+                </mixPort>
+                <mixPort name="direct a2dp" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name=""/>
+                </mixPort>
+                <mixPort name="echo reference" role="sink">
+                    <profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+                <mixPort name="built-in mic" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="16000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+                <mixPort name="ble_in" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER">
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-10000"
+                              maxValueMB="0"
+                              defaultValueMB="-6000"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="HDMI Out" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
+                </devicePort>
+                <devicePort tagName="Tuner" role="source" type="AUDIO_DEVICE_IN_TV_TUNER">
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-10000"
+                              maxValueMB="0"
+                              defaultValueMB="-6000"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source" address="top">
+                    <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                    <profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BLE-In" type="AUDIO_DEVICE_IN_BLUETOOTH_BLE" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+            </devicePorts>
+            <!-- route declaration, i.e. list all available sources for a given sink -->
+            <routes>
+                <route type="mix" sink="HDMI Out"
+                       sources="primary output,tunnel pcm,direct output,Tuner,mmap_no_irq_out,tunnel direct output"/>
+                <route type="mix" sink="Speaker"
+                       sources="primary output,tunnel pcm,direct pcm,BT SCO Headset Mic,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="BT SCO"
+                       sources="primary output,BT SCO Headset Mic,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="BT SCO Headset"
+                       sources="primary output,BT SCO Headset Mic,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="Wired Headset"
+                       sources="primary output,tunnel pcm,BT SCO Headset Mic,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="Wired Headphones"
+                       sources="primary output,tunnel pcm,BT SCO Headset Mic,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="primary input"
+                       sources="Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,Tuner"/>
+                <route type="mix" sink="BT A2DP Out"
+                       sources="primary output,tunnel a2dp,direct a2dp,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="BT A2DP Headphones"
+                       sources="primary output,tunnel a2dp,direct a2dp,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="BT A2DP Speaker"
+                       sources="primary output,tunnel a2dp,direct a2dp,Tuner,mmap_no_irq_out"/>
+                <route type="mix" sink="echo reference"
+                       sources="Echo Reference"/>
+                <route type="mix" sink="built-in mic"
+                       sources="Built-In Mic"/>
+                <route type="mix" sink="ble_in"
+                       sources="BLE-In"/>
+            </routes>
+
+        </module>
+
+        <!-- A2dp Audio HAL -->
+        <!-- <xi:include href="a2dp_audio_policy_configuration.xml"/> -->
+
+        <!-- Usb Audio HAL -->
+        <!-- <xi:include href="usb_audio_policy_configuration.xml"/> -->
+
+        <!-- Remote Submix Audio HAL -->
+        <!-- <xi:include href="r_submix_audio_policy_configuration.xml"/> -->
+
+        <!-- Hearing aid Audio HAL -->
+        <!-- <xi:include href="hearing_aid_audio_policy_configuration.xml"/> -->
+
+        <!-- MSD Audio HAL (optional) -->
+        <!-- <xi:include href="msd_audio_policy_configuration.xml"/> -->
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section -->
+
+    <!-- <xi:include href="audio_policy_volumes.xml"/> -->
+    <!-- <xi:include href="default_volume_tables.xml"/> -->
+
+    <!-- End of Volume section -->
+
+    <!-- Surround Sound configuration -->
+
+    <surroundSound>
+    <!-- Each of the listed formats gets an entry in Surround Settings dialog on TV devices.
+        There must be a corresponding Java ENCODING_... constant defined in AudioFormat.java,
+        and a display name defined in AudioFormat.toDisplayName. For the formats that don't
+        need a dedicated Surrond Settings dialog entry, a subformats list has to be used. -->
+        <formats>
+            <format name="AUDIO_FORMAT_AC3" />
+            <format name="AUDIO_FORMAT_E_AC3" />
+            <format name="AUDIO_FORMAT_E_AC3_JOC" />
+            <format name="AUDIO_FORMAT_DTS" />
+        </formats>
+    </surroundSound>
+
+    <!-- End of Surround Sound configuration -->
+
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
index 583ff01..7caa712 100644
--- a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -128,5 +128,11 @@
 }
 
 // Target file names are the same for all versions, see 'HalAudioVx_0GeneratorTest.xml' test configs
+// clang-format off
 INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
-                         ::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"));
+                         ::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"
+#if MAJOR_VERSION == 7
+                                         , "apm_config_b_204314749_7_0.xml"
+#endif
+                                           ));
+// clang-format on
diff --git a/bluetooth/a2dp/1.0/vts/OWNERS b/bluetooth/a2dp/1.0/vts/OWNERS
index 4e982a1..d3aab51 100644
--- a/bluetooth/a2dp/1.0/vts/OWNERS
+++ b/bluetooth/a2dp/1.0/vts/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 27441
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
diff --git a/bluetooth/audio/2.0/vts/OWNERS b/bluetooth/audio/2.0/vts/OWNERS
index b6c0813..b266b06 100644
--- a/bluetooth/audio/2.0/vts/OWNERS
+++ b/bluetooth/audio/2.0/vts/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
diff --git a/bluetooth/audio/2.1/vts/OWNERS b/bluetooth/audio/2.1/vts/OWNERS
index b6c0813..b266b06 100644
--- a/bluetooth/audio/2.1/vts/OWNERS
+++ b/bluetooth/audio/2.1/vts/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
index eeff4de..7fb5b6c 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
@@ -16,7 +16,10 @@
 
 package android.hardware.bluetooth.audio@2.2;
 
+import IBluetoothAudioProvider;
 import @2.1::IBluetoothAudioProvidersFactory;
+import @2.0::Status;
+import @2.1::SessionType;
 
 /**
  * This factory allows a HAL implementation to be split into multiple
@@ -30,4 +33,19 @@
  * for return value must be invoked synchronously before the API call returns.
  */
 interface IBluetoothAudioProvidersFactory extends @2.1::IBluetoothAudioProvidersFactory {
+    /**
+     * Opens an audio provider for a session type. To close the provider, it is
+     * necessary to release references to the returned provider object.
+     *
+     * @param sessionType The session type (e.g.
+     *    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+     *
+     * @return status One of the following
+     *    SUCCESS if the Audio HAL successfully opens the provider with the
+     *        given session type
+     *    FAILURE if the Audio HAL cannot open the provider
+     * @return provider The provider of the specified session type
+     */
+    openProvider_2_2(SessionType sessionType)
+        generates (Status status, IBluetoothAudioProvider provider);
 };
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 7438c80..510833d 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -122,6 +122,49 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvidersFactory::openProvider_2_2(
+    const V2_1::SessionType sessionType, openProvider_2_2_cb _hidl_cb) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
+  BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
+  BluetoothAudioProvider* provider = nullptr;
+
+  switch (sessionType) {
+    case V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+      provider = &a2dp_software_provider_instance_;
+      break;
+    case V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
+      provider = &a2dp_offload_provider_instance_;
+      break;
+    case V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+      provider = &hearing_aid_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+      provider = &leaudio_output_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      provider = &leaudio_offload_output_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
+      provider = &leaudio_input_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+      provider = &leaudio_offload_input_provider_instance_;
+      break;
+    default:
+      status = BluetoothAudioStatus::FAILURE;
+  }
+
+  if (provider == nullptr || !provider->isValid(sessionType)) {
+    provider = nullptr;
+    status = BluetoothAudioStatus::FAILURE;
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
+               << ", status=" << toString(status);
+  }
+
+  _hidl_cb(status, provider);
+  return Void();
+}
+
 Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
     const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
   hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
index 8db330b..658249b 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
@@ -46,6 +46,9 @@
   Return<void> openProvider_2_1(const V2_1::SessionType sessionType,
                                 openProvider_2_1_cb _hidl_cb) override;
 
+  Return<void> openProvider_2_2(const V2_1::SessionType sessionType,
+                                openProvider_2_2_cb _hidl_cb) override;
+
   Return<void> getProviderCapabilities_2_1(
       const V2_1::SessionType sessionType,
       getProviderCapabilities_2_1_cb _hidl_cb) override;
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
index a35dde2..ed92847 100644
--- a/bluetooth/audio/utils/OWNERS
+++ b/bluetooth/audio/utils/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
new file mode 100644
index 0000000..e20914e
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "BluetoothAudioSession_2_2.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionControl_2_2 {
+  using SessionType_2_1 =
+      ::android::hardware::bluetooth::audio::V2_1::SessionType;
+  using AudioConfiguration_2_2 =
+      ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
+
+ public:
+  // The control API helps to check if session is ready or not
+  // @return: true if the Bluetooth stack has started th specified session
+  static bool IsSessionReady(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->IsSessionReady();
+    }
+    return false;
+  }
+
+  // The control API helps the bluetooth_audio module to register
+  // PortStatusCallbacks
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+    }
+    return kObserversCookieUndefined;
+  }
+
+  // The control API helps the bluetooth_audio module to unregister
+  // PortStatusCallbacks
+  // @param: cookie - indicates which bluetooth_audio output is
+  static void UnregisterControlResultCback(const SessionType_2_1& session_type,
+                                           uint16_t cookie) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+    }
+  }
+
+  // The control API for the bluetooth_audio module to get current
+  // AudioConfiguration
+  static const AudioConfiguration_2_2 GetAudioConfig(
+      const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioConfig();
+    } else if (session_type ==
+               SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+      return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
+    } else {
+      return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
+    }
+  }
+
+  // Those control APIs for the bluetooth_audio module to start / suspend / stop
+  // stream, to check position, and to update metadata.
+  static bool StartStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->StartStream();
+    }
+    return false;
+  }
+
+  static bool SuspendStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->SuspendStream();
+    }
+    return false;
+  }
+
+  static void StopStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->StopStream();
+    }
+  }
+
+  static bool GetPresentationPosition(const SessionType_2_1& session_type,
+                                      uint64_t* remote_delay_report_ns,
+                                      uint64_t* total_bytes_readed,
+                                      timespec* data_position) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->GetPresentationPosition(
+          remote_delay_report_ns, total_bytes_readed, data_position);
+    }
+    return false;
+  }
+
+  static void UpdateTracksMetadata(
+      const SessionType_2_1& session_type,
+      const struct source_metadata* source_metadata) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->UpdateTracksMetadata(source_metadata);
+    }
+  }
+
+  // The control API writes stream to FMQ
+  static size_t OutWritePcmData(const SessionType_2_1& session_type,
+                                const void* buffer, size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes);
+    }
+    return 0;
+  }
+
+  // The control API reads stream from FMQ
+  static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
+                              size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
+    }
+    return 0;
+  }
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 9d9ea41..5a6b2e7 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -29,6 +29,9 @@
 using SessionType_2_0 =
     ::android::hardware::bluetooth::audio::V2_0::SessionType;
 
+using AudioConfiguration_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
+
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
@@ -52,7 +55,9 @@
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
         session_type)
     : audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
-          static_cast<SessionType_2_0>(session_type))) {
+          static_cast<SessionType_2_0>(session_type))),
+      audio_session_2_1(
+          BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type)) {
   if (is_2_0_session_type(session_type)) {
     session_type_2_1_ = (SessionType_2_1::UNKNOWN);
   } else {
@@ -74,6 +79,10 @@
 BluetoothAudioSession_2_2::GetAudioSession() {
   return audio_session;
 }
+std::shared_ptr<BluetoothAudioSession_2_1>
+BluetoothAudioSession_2_2::GetAudioSession_2_1() {
+  return audio_session_2_1;
+}
 
 // The control function is for the bluetooth_audio module to get the current
 // AudioConfiguration
@@ -82,7 +91,19 @@
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (IsSessionReady()) {
     // If session is unknown it means it should be 2.0 type
-    if (session_type_2_1_ != SessionType_2_1::UNKNOWN) return audio_config_2_2_;
+    if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
+      if (audio_config_2_2_ != invalidSoftwareAudioConfiguration)
+        return audio_config_2_2_;
+
+      ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
+      const AudioConfiguration_2_1 fromConf =
+          GetAudioSession_2_1()->GetAudioConfig();
+      if (fromConf.getDiscriminator() ==
+          AudioConfiguration_2_1::hidl_discriminator::pcmConfig) {
+        toConf.pcmConfig() = fromConf.pcmConfig();
+        return toConf;
+      }
+    }
 
     ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
     const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index d3d0bd3..7213ede 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -22,6 +22,7 @@
 #include <unordered_map>
 
 #include "BluetoothAudioSession.h"
+#include "BluetoothAudioSession_2_1.h"
 
 namespace android {
 namespace bluetooth {
@@ -30,6 +31,7 @@
 class BluetoothAudioSession_2_2 {
  private:
   std::shared_ptr<BluetoothAudioSession> audio_session;
+  std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1;
 
   ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
 
@@ -56,6 +58,7 @@
   bool IsSessionReady();
 
   std::shared_ptr<BluetoothAudioSession> GetAudioSession();
+  std::shared_ptr<BluetoothAudioSession_2_1> GetAudioSession_2_1();
 
   // The report function is used to report that the Bluetooth stack has started
   // this session without any failure, and will invoke session_changed_cb_ to
diff --git a/camera/metadata/3.7/Android.bp b/camera/metadata/3.7/Android.bp
new file mode 100644
index 0000000..14981b8
--- /dev/null
+++ b/camera/metadata/3.7/Android.bp
@@ -0,0 +1,26 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.camera.metadata@3.7",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.metadata@3.2",
+        "android.hardware.camera.metadata@3.3",
+        "android.hardware.camera.metadata@3.4",
+        "android.hardware.camera.metadata@3.5",
+        "android.hardware.camera.metadata@3.6",
+    ],
+    gen_java: true,
+}
diff --git a/camera/metadata/3.8/Android.bp b/camera/metadata/3.8/Android.bp
new file mode 100644
index 0000000..ead9543
--- /dev/null
+++ b/camera/metadata/3.8/Android.bp
@@ -0,0 +1,27 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.camera.metadata@3.8",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.metadata@3.2",
+        "android.hardware.camera.metadata@3.3",
+        "android.hardware.camera.metadata@3.4",
+        "android.hardware.camera.metadata@3.5",
+        "android.hardware.camera.metadata@3.6",
+        "android.hardware.camera.metadata@3.7",
+    ],
+    gen_java: true,
+}
diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal
index dcee775..b20af18 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -58,3 +58,11 @@
 /*
  * Enumeration definitions for the various entries that need them
  */
+
+/** android.control.videoStabilizationMode enumeration values added since v3.2
+ * @see ANDROID_CONTROL_VIDEO_STABILIZATION_MODE
+ */
+enum CameraMetadataEnumAndroidControlVideoStabilizationMode :
+        @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode {
+    ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
+};
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 62de3af..d02547c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -936,6 +936,9 @@
             camera_metadata_ro_entry* streamConfigs,
             camera_metadata_ro_entry* maxResolutionStreamConfigs,
             const camera_metadata_t* staticMetadata);
+    void getPrivacyTestPatternModes(
+            const camera_metadata_t* staticMetadata,
+            std::unordered_set<int32_t>* privacyTestPatternModes/*out*/);
     static bool isColorCamera(const camera_metadata_t *metadata);
 
     static V3_2::DataspaceFlags getDataspace(PixelFormat format);
@@ -6762,6 +6765,25 @@
     ASSERT_TRUE(-ENOENT == retcode || 0 == retcode);
 }
 
+void CameraHidlTest::getPrivacyTestPatternModes(
+        const camera_metadata_t* staticMetadata,
+        std::unordered_set<int32_t>* privacyTestPatternModes/*out*/) {
+    ASSERT_NE(staticMetadata, nullptr);
+    ASSERT_NE(privacyTestPatternModes, nullptr);
+
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(
+            staticMetadata, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &entry);
+    ASSERT_TRUE(0 == retcode);
+
+    for (auto i = 0; i < entry.count; i++) {
+        if (entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR ||
+                entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK) {
+            privacyTestPatternModes->insert(entry.data.i32[i]);
+        }
+    }
+}
+
 // Select an appropriate dataspace given a specific pixel format.
 V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) {
     switch (format) {
@@ -7816,6 +7838,16 @@
         ASSERT_TRUE(isUltraHighResCamera && !isMultiCamera);
         physicalIds.insert(cameraId);
     }
+
+    std::unordered_set<int32_t> physicalRequestKeyIDs;
+    rc = getSupportedKeys(const_cast<camera_metadata_t *>(metadata),
+            ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
+    ASSERT_TRUE(Status::OK == rc);
+    bool hasTestPatternPhysicalRequestKey = physicalRequestKeyIDs.find(
+            ANDROID_SENSOR_TEST_PATTERN_MODE) != physicalRequestKeyIDs.end();
+    std::unordered_set<int32_t> privacyTestPatternModes;
+    getPrivacyTestPatternModes(metadata, &privacyTestPatternModes);
+
     // Map from image format to number of multi-resolution sizes for that format
     std::unordered_map<int32_t, size_t> multiResOutputFormatCounterMap;
     std::unordered_map<int32_t, size_t> multiResInputFormatCounterMap;
@@ -7837,6 +7869,7 @@
         camera_metadata_ro_entry physicalStreamConfigs;
         camera_metadata_ro_entry physicalMaxResolutionStreamConfigs;
         bool isUltraHighRes = false;
+        std::unordered_set<int32_t> subCameraPrivacyTestPatterns;
         if (isPublicId) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> subDevice;
             Return<void> ret;
@@ -7867,6 +7900,8 @@
                         &physicalMultiResStreamConfigs, &physicalStreamConfigs,
                         &physicalMaxResolutionStreamConfigs, staticMetadata);
                 isUltraHighRes = isUltraHighResolution(staticMetadata);
+
+                getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
             });
             ASSERT_TRUE(ret.isOk());
         } else {
@@ -7893,6 +7928,7 @@
                                 &physicalMultiResStreamConfigs, &physicalStreamConfigs,
                                 &physicalMaxResolutionStreamConfigs, staticMetadata);
                         isUltraHighRes = isUltraHighResolution(staticMetadata);
+                        getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
                     });
             ASSERT_TRUE(ret.isOk());
 
@@ -7909,6 +7945,10 @@
             ASSERT_TRUE(ret.isOk());
         }
 
+        if (hasTestPatternPhysicalRequestKey) {
+            ASSERT_TRUE(privacyTestPatternModes == subCameraPrivacyTestPatterns);
+        }
+
         if (physicalMultiResStreamConfigs.count > 0) {
             ASSERT_GE(deviceVersion, CAMERA_DEVICE_API_VERSION_3_7);
             ASSERT_EQ(physicalMultiResStreamConfigs.count % 4, 0);
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5e65849..5d92304 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -248,6 +248,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.gnss</name>
+        <version>2</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 3c9c29a..a73182e 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -27,7 +27,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 695246a..769e8ae 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -50,7 +50,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index c46c735..2979f5c 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -44,7 +44,7 @@
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
similarity index 70%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
index d7eecbb..54c126c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
@@ -31,8 +31,27 @@
 // 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.radio.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable GnssLocation {
+  int gnssLocationFlags;
+  double latitudeDegrees;
+  double longitudeDegrees;
+  double altitudeMeters;
+  double speedMetersPerSec;
+  double bearingDegrees;
+  double horizontalAccuracyMeters;
+  double verticalAccuracyMeters;
+  double speedAccuracyMetersPerSecond;
+  double bearingAccuracyDegrees;
+  long timestampMillis;
+  android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+  const int HAS_LAT_LONG = 1;
+  const int HAS_ALTITUDE = 2;
+  const int HAS_SPEED = 4;
+  const int HAS_BEARING = 8;
+  const int HAS_HORIZONTAL_ACCURACY = 16;
+  const int HAS_VERTICAL_ACCURACY = 32;
+  const int HAS_SPEED_ACCURACY = 64;
+  const int HAS_BEARING_ACCURACY = 128;
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index f93b496..52276b4 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -36,10 +36,11 @@
 interface IGnss {
   void setCallback(in android.hardware.gnss.IGnssCallback callback);
   void close();
-  android.hardware.gnss.IGnssPsds getExtensionPsds();
+  @nullable android.hardware.gnss.IGnssPsds getExtensionPsds();
   android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
   android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
   android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
+  @nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
index d7eecbb..492edc3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
@@ -31,8 +31,14 @@
 // 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.radio.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssBatching {
+  void init(in android.hardware.gnss.IGnssBatchingCallback callback);
+  int getBatchSize();
+  void start(in long periodNanos, in int flags);
+  void flush();
+  void stop();
+  void cleanup();
+  const int WAKEUP_ON_FIFO_FULL = 1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
similarity index 91%
rename from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
index d7eecbb..427137a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -31,8 +31,8 @@
 // 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.radio.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssBatchingCallback {
+  void gnssLocationBatchCb(in android.hardware.gnss.GnssLocation[] locations);
 }
diff --git a/gnss/aidl/android/hardware/gnss/GnssLocation.aidl b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
new file mode 100644
index 0000000..25aea4d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.gnss;
+
+import android.hardware.gnss.ElapsedRealtime;
+
+/** Represents a location. */
+@VintfStability
+parcelable GnssLocation {
+    /** Bit mask to indicate GnssLocation has valid latitude and longitude. */
+    const int HAS_LAT_LONG = 0x0001;
+    /** Bit mask to indicate GnssLocation has valid altitude. */
+    const int HAS_ALTITUDE = 0x0002;
+    /** Bit mask to indicate GnssLocation has valid speed. */
+    const int HAS_SPEED = 0x0004;
+    /** Bit mask to indicate GnssLocation has valid bearing. */
+    const int HAS_BEARING = 0x0008;
+    /** Bit mask to indicate GnssLocation has valid horizontal accuracy. */
+    const int HAS_HORIZONTAL_ACCURACY = 0x0010;
+    /** Bit mask to indicate GnssLocation has valid vertical accuracy. */
+    const int HAS_VERTICAL_ACCURACY = 0x0020;
+    /** Bit mask to indicate GnssLocation has valid speed accuracy. */
+    const int HAS_SPEED_ACCURACY = 0x0040;
+    /** Bit mask to indicate GnssLocation has valid bearing accuracy. */
+    const int HAS_BEARING_ACCURACY = 0x0080;
+
+    /** A bit field of flags indicating the validity of the fields in this GnssLocation. */
+    int gnssLocationFlags;
+
+    /** Represents latitude in degrees. */
+    double latitudeDegrees;
+
+    /** Represents longitude in degrees. */
+    double longitudeDegrees;
+
+    /** Represents altitude in meters above the WGS 84 reference ellipsoid. */
+    double altitudeMeters;
+
+    /** Represents speed in meters per second. */
+    double speedMetersPerSec;
+
+    /** Represents heading in degrees. */
+    double bearingDegrees;
+
+    /**
+     * Represents expected horizontal position accuracy, radial, in meters (68% confidence).
+     */
+    double horizontalAccuracyMeters;
+
+    /**
+     * Represents expected vertical position accuracy in meters (68% confidence).
+     */
+    double verticalAccuracyMeters;
+
+    /**
+     * Represents expected speed accuracy in meter per seconds (68% confidence).
+     */
+    double speedAccuracyMetersPerSecond;
+
+    /**
+     * Represents expected bearing accuracy in degrees (68% confidence).
+     */
+    double bearingAccuracyDegrees;
+
+    /** Timestamp for the location fix in milliseconds since January 1, 1970. */
+    long timestampMillis;
+
+    /**
+     * Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
+     * clock.
+     *
+     * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
+     * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
+     * needs to be estimated by syncing the notion of time via PTP or some other mechanism.
+     */
+    ElapsedRealtime elapsedRealtime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index f99b512..b12fb82 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.IGnssBatching;
 import android.hardware.gnss.IGnssCallback;
 import android.hardware.gnss.IGnssConfiguration;
 import android.hardware.gnss.IGnssMeasurementInterface;
@@ -27,9 +28,8 @@
  */
 @VintfStability
 interface IGnss {
-
     /**
-     * All GNSS Binder calls may return a ServiceSpecificException with the following error
+     * All GNSS binder calls may return a ServiceSpecificException with the following error
      * codes.
      */
     const int ERROR_INVALID_ARGUMENT = 1;
@@ -73,11 +73,9 @@
     /**
      * This method returns the IGnssPsds interface.
      *
-     * This method must return non-null.
-     *
      * @return Handle to the IGnssPsds interface.
      */
-    IGnssPsds getExtensionPsds();
+    @nullable IGnssPsds getExtensionPsds();
 
     /**
      * This method returns the IGnssConfiguration interface.
@@ -89,7 +87,7 @@
     IGnssConfiguration getExtensionGnssConfiguration();
 
     /**
-     * This methods returns the IGnssMeasurementInterface interface.
+     * This method returns the IGnssMeasurementInterface interface.
      *
      * This method must return non-null.
      *
@@ -105,4 +103,11 @@
      * @return Handle to the IGnssPowerIndication interface.
      */
     IGnssPowerIndication getExtensionGnssPowerIndication();
+
+    /**
+     * This method returns the IGnssBatching interface.
+     *
+     * @return Handle to the IGnssBatching interface.
+     */
+    @nullable IGnssBatching getExtensionGnssBatching();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
new file mode 100644
index 0000000..0d48ee1
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 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.gnss;
+
+import android.hardware.gnss.IGnssBatchingCallback;
+
+/**
+ * Extended interface for GNSS Batching support.
+ *
+ * If this interface is supported, this batching request must be able to run in parallel with, or
+ * without, non-batched location requested by the IGnss start() & stop() - i.e. both requests must
+ * be handled independently, and not interfere with each other.
+ *
+ * For example, if a 1Hz continuous output is underway on the IGnssCallback, due to an IGnss start()
+ * operation, and then a IGnssBatching start() is called for a location every 10 seconds, the newly
+ * added batching request must not disrupt the 1Hz continuous location output on the IGnssCallback.
+ *
+ * As with GNSS Location outputs, source of location must be GNSS satellite measurements, optionally
+ * using interial and baro sensors to improve relative motion filtering. No additional absolute
+ * positioning information, such as WiFi derived location, may be mixed with the GNSS information.
+ */
+@VintfStability
+interface IGnssBatching {
+    /**
+     * Bit mask indicating batching supports wake up and flush when FIFO is full.
+     *
+     * If this flag is set, the hardware implementation must wake up the application processor when
+     * the FIFO is full, and call IGnssBatchingCallback to return the locations.
+     *
+     * If the flag is not set, the hardware implementation must drop the oldest data when the FIFO
+     * is full.
+     */
+    const int WAKEUP_ON_FIFO_FULL = 0x01;
+
+    /**
+     * Open the interface and provides the callback routines to the implementation of this
+     * interface.
+     *
+     * @param callback Callback interface for IGnssBatching.
+     */
+    void init(in IGnssBatchingCallback callback);
+
+    /**
+     * Return the batch size (in number of GnssLocation objects) available in this hardware
+     * implementation.
+     *
+     * If the available size is variable, for example, based on other operations consuming memory,
+     * this is the minimum size guaranteed to be available for batching operations.
+     *
+     * This may, for example, be used by the client, to decide on the batching interval and whether
+     * the AP should be woken up or not.
+     *
+     * @return the number of location objects supported per batch
+     */
+    int getBatchSize();
+
+    /**
+     * Start batching locations. This API is primarily used when the AP is asleep and the device can
+     * batch locations in the hardware.
+     *
+     * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+     * location.
+     *
+     * When the buffer is full and WAKEUP_ON_FIFO_FULL is used, IGnssBatchingCallback must be called
+     * to return the locations.
+     *
+     * When the buffer is full and WAKEUP_ON_FIFO_FULL is not set, the oldest location object is
+     * dropped. In this case the AP must not be woken up. The AP would then generally be responsible
+     * for using flushBatchedLocation to explicitly ask for the location as needed, to avoid it
+     * being dropped.
+     *
+     * @param periodNanos  Time interval between samples in the location batch, in nanoseconds
+     * @param flags  A bitfield of flags (WAKEUP_ON_FIFO_FULL) indicating the batching behavior
+     */
+    void start(in long periodNanos, in int flags);
+
+    /**
+     * Retrieve all batched locations currently stored.
+     *
+     * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+     * location.
+     *
+     * IGnssBatchingCallback must be called in response, even if there are no locations to flush
+     * (in which case the Location vector must be empty).
+     *
+     * Subsequent calls to flush must not return any of the locations returned in this call.
+     */
+    void flush();
+
+    /**
+     * Stop batching.
+     */
+    void stop();
+
+    /**
+     * Closes the interface. If any batch operations are in progress, they must be stopped.  If any
+     * locations are in the hardware batch, they must be deleted (and not sent via callback.)
+     *
+     * init() may be called again, after this, if the interface is to be restored
+     */
+    void cleanup();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
new file mode 100644
index 0000000..b1bfc57
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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.gnss;
+
+import android.hardware.gnss.GnssLocation;
+
+/** The callback interface to report batched GNSS locations from the HAL. */
+@VintfStability
+interface IGnssBatchingCallback {
+    /**
+     * Called when a batch of locations is output, by various means, including
+     * a flush request, as well as the buffer becoming full (if appropriate option
+     * is set.)
+     *
+     * All locations returned by this callback must be cleared from the hardware
+     * buffer, such the sequential calls of this callback do not return any
+     * redundant locations.  (Same lat/lon, at a new time, is acceptable.)
+     *
+     * @param locations A list of GNSS Locations
+     */
+    void gnssLocationBatchCb(in GnssLocation[] locations);
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index c028dd7..892ad15 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -52,10 +52,11 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     srcs: [
         "Gnss.cpp",
+        "GnssBatching.cpp",
         "GnssHidlHal.cpp",
         "GnssPowerIndication.cpp",
         "GnssPsds.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 6061eec..fbfa2bb 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,6 +18,7 @@
 
 #include "Gnss.h"
 #include <log/log.h>
+#include "GnssBatching.h"
 #include "GnssConfiguration.h"
 #include "GnssMeasurementInterface.h"
 #include "GnssPsds.h"
@@ -88,4 +89,11 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+    ALOGD("Gnss::getExtensionGnssBatching");
+
+    *iGnssBatching = SharedRefBase::make<GnssBatching>();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 76ebe4d..3959ef8 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
@@ -37,6 +38,8 @@
             std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
     ndk::ScopedAStatus getExtensionGnssMeasurement(
             std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
+    ndk::ScopedAStatus getExtensionGnssBatching(
+            std::shared_ptr<IGnssBatching>* iGnssBatching) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssBatching.cpp b/gnss/aidl/default/GnssBatching.cpp
new file mode 100644
index 0000000..b8be5e5
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 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 "GnssBatchingAidl"
+
+#include "GnssBatching.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+
+constexpr int BATCH_SIZE = 10;
+
+std::shared_ptr<IGnssBatchingCallback> GnssBatching::sCallback = nullptr;
+
+GnssBatching::GnssBatching()
+    : mMinIntervalMs(1000),
+      mWakeUpOnFifoFull(false),
+      mBatchedLocations(std::vector<GnssLocation>()) {}
+GnssBatching::~GnssBatching() {
+    cleanup();
+}
+
+ndk::ScopedAStatus GnssBatching::init(const std::shared_ptr<IGnssBatchingCallback>& callback) {
+    ALOGD("init");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::getBatchSize(int* size) {
+    ALOGD("getBatchingSize");
+    *size = BATCH_SIZE;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::start(int64_t periodNanos, int flags) {
+    ALOGD("start: periodNanos=%" PRId64 ", flags=%d", periodNanos, flags);
+    if (mIsActive) {
+        ALOGW("Gnss has started. Restarting...");
+        stop();
+    }
+
+    mWakeUpOnFifoFull = (flags & IGnssBatching::WAKEUP_ON_FIFO_FULL) ? true : false;
+    // mMinIntervalMs is not smaller than 1 sec
+    periodNanos = (periodNanos < 1e9) ? 1e9 : periodNanos;
+    mMinIntervalMs = periodNanos / 1e6;
+
+    mIsActive = true;
+    mThread = std::thread([this]() {
+        while (mIsActive == true) {
+            const auto location = common::Utils::getMockLocation();
+            this->batchLocation(location);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+        }
+    });
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::flush() {
+    ALOGD("flush");
+    std::vector<GnssLocation> copy = std::vector<GnssLocation>(mBatchedLocations);
+    ndk::ScopedAStatus status;
+    if (sCallback != nullptr) {
+        sCallback->gnssLocationBatchCb(copy);
+        status = ndk::ScopedAStatus::ok();
+    } else {
+        ALOGE("GnssBatchingCallback is null. flush() failed.");
+        status = ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_GENERIC);
+    }
+    mBatchedLocations.clear();
+    return status;
+}
+
+ndk::ScopedAStatus GnssBatching::stop() {
+    ALOGD("stop");
+    // Do not call flush() at stop()
+    mIsActive = false;
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::cleanup() {
+    ALOGD("cleanup");
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (mIsActive) {
+        stop();
+    }
+    flush();
+
+    sCallback = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+void GnssBatching::batchLocation(const GnssLocation& location) {
+    if (mBatchedLocations.size() > BATCH_SIZE) {
+        mBatchedLocations.erase(mBatchedLocations.begin());
+    }
+    mBatchedLocations.push_back(location);
+    if (mWakeUpOnFifoFull && mBatchedLocations.size() == BATCH_SIZE) {
+        flush();
+    }
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssBatching.h b/gnss/aidl/default/GnssBatching.h
new file mode 100644
index 0000000..7cd6e85
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssBatching : public BnGnssBatching {
+  public:
+    GnssBatching();
+    ~GnssBatching();
+    ndk::ScopedAStatus init(const std::shared_ptr<IGnssBatchingCallback>& callback) override;
+    ndk::ScopedAStatus getBatchSize(int* size) override;
+    ndk::ScopedAStatus start(int64_t periodNanos, int flags) override;
+    ndk::ScopedAStatus flush() override;
+    ndk::ScopedAStatus stop() override;
+    ndk::ScopedAStatus cleanup() override;
+
+  private:
+    void batchLocation(const GnssLocation&);
+
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssBatchingCallback> sCallback;
+
+    std::thread mThread;
+    std::atomic<bool> mIsActive;
+    std::atomic<long> mMinIntervalMs;
+    std::atomic<bool> mWakeUpOnFifoFull;
+
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+
+    std::vector<GnssLocation> mBatchedLocations;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index 2b06cd2..7449310 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,6 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.gnss</name>
+        <version>2</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 838849d..6096d4d 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -30,6 +30,7 @@
     srcs: [
         "gnss_hal_test.cpp",
         "gnss_hal_test_cases.cpp",
+        "GnssBatchingCallback.cpp",
         "GnssCallbackAidl.cpp",
         "GnssMeasurementCallbackAidl.cpp",
         "GnssPowerIndicationCallback.cpp",
@@ -43,7 +44,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.gnss-V1-cpp",
+        "android.hardware.gnss-V2-cpp",
         "android.hardware.gnss@common-vts-lib",
     ],
     test_suites: [
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
new file mode 100644
index 0000000..2da3b12
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssBatchingCallback.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+android::binder::Status GnssBatchingCallback::gnssLocationBatchCb(
+        const std::vector<android::hardware::gnss::GnssLocation>& locations) {
+    ALOGI("Batched locations received with size=%d", (int)locations.size());
+    for (const auto& location : locations) {
+        ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+              location.elapsedRealtime.flags, location.elapsedRealtime.timestampNs,
+              location.elapsedRealtime.timeUncertaintyNs);
+    }
+    batched_locations_cbq_.store(locations);
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssBatchingCallback.h b/gnss/aidl/vts/GnssBatchingCallback.h
new file mode 100644
index 0000000..310a134
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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 <android/hardware/gnss/BnGnssBatchingCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssBatchingCallback. */
+class GnssBatchingCallback : public android::hardware::gnss::BnGnssBatchingCallback {
+  public:
+    GnssBatchingCallback() : batched_locations_cbq_("batched_locations") {}
+    ~GnssBatchingCallback() {}
+
+    android::binder::Status gnssLocationBatchCb(
+            const std::vector<android::hardware::gnss::GnssLocation>& locations) override;
+
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<android::hardware::gnss::GnssLocation>>
+            batched_locations_cbq_;
+    std::vector<android::hardware::gnss::GnssLocation> last_batched_locations_;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index f72f7fe..e3ecbed 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -23,6 +23,7 @@
 #include <binder/IServiceManager.h>
 
 #include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssBatchingCallback.h"
 #include "GnssCallbackAidl.h"
 #include "v2_1/gnss_hal_test_template.h"
 
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 0cd782e..86140cc 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -17,10 +17,12 @@
 #define LOG_TAG "GnssHalTestCases"
 
 #include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssBatching.h>
 #include <android/hardware/gnss/IGnssMeasurementCallback.h>
 #include <android/hardware/gnss/IGnssMeasurementInterface.h>
 #include <android/hardware/gnss/IGnssPowerIndication.h>
 #include <android/hardware/gnss/IGnssPsds.h>
+#include "GnssBatchingCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
 #include "GnssPowerIndicationCallback.h"
 #include "gnss_hal_test.h"
@@ -33,6 +35,8 @@
 using android::hardware::gnss::GnssMeasurement;
 using android::hardware::gnss::GnssPowerStats;
 using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssBatching;
+using android::hardware::gnss::IGnssBatchingCallback;
 using android::hardware::gnss::IGnssConfiguration;
 using android::hardware::gnss::IGnssMeasurementCallback;
 using android::hardware::gnss::IGnssMeasurementInterface;
@@ -749,3 +753,25 @@
     status = gnss_configuration_hal->setBlocklist(sources);
     ASSERT_TRUE(status.isOk());
 }
+
+/*
+ * TestGnssBatchingExtension:
+ * 1. Gets the IGnssBatching extension.
+ * 2. Initializes the interface with an IGnssBatchingCallback.
+ * 3. Clean up.
+ */
+TEST_P(GnssHalTest, TestGnssBatchingExtension) {
+    sp<IGnssBatching> iGnssBatching;
+    auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
+    if (!status.isOk() || iGnssBatching == nullptr) {
+        // Device doesn't support batching. Skip the test.
+        return;
+    }
+
+    sp<IGnssBatchingCallback> iGnssBatchingCallback;
+    status = iGnssBatching->init(iGnssBatchingCallback);
+    ASSERT_TRUE(status.isOk());
+
+    status = iGnssBatching->cleanup();
+    ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 5294409..05bec88 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -56,6 +56,6 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
 }
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index dfcf9a9..c339e72 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -28,6 +28,7 @@
 using aidl::android::hardware::gnss::ElapsedRealtime;
 using aidl::android::hardware::gnss::GnssClock;
 using aidl::android::hardware::gnss::GnssData;
+using aidl::android::hardware::gnss::GnssLocation;
 using aidl::android::hardware::gnss::GnssMeasurement;
 using aidl::android::hardware::gnss::IGnss;
 using aidl::android::hardware::gnss::IGnssMeasurementCallback;
@@ -232,6 +233,30 @@
     return gnssData;
 }
 
+GnssLocation Utils::getMockLocation() {
+    ElapsedRealtime elapsedRealtime = {
+            .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = ::android::elapsedRealtimeNano(),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+    GnssLocation location = {.gnssLocationFlags = 0xFF,
+                             .latitudeDegrees = gMockLatitudeDegrees,
+                             .longitudeDegrees = gMockLongitudeDegrees,
+                             .altitudeMeters = gMockAltitudeMeters,
+                             .speedMetersPerSec = gMockSpeedMetersPerSec,
+                             .bearingDegrees = gMockBearingDegrees,
+                             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+                             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+                             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+                             .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+                             .timestampMillis = static_cast<int64_t>(
+                                     kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6),
+                             .elapsedRealtime = elapsedRealtime};
+    return location;
+}
+
 V2_0::GnssLocation Utils::getMockLocationV2_0() {
     const V2_0::ElapsedRealtime timestamp = {
             .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 43772ce..4500ee6 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -17,6 +17,7 @@
 #ifndef android_hardware_gnss_common_default_Utils_H_
 #define android_hardware_gnss_common_default_Utils_H_
 
+#include <aidl/android/hardware/gnss/BnGnss.h>
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <android/hardware/gnss/1.0/IGnss.h>
 #include <android/hardware/gnss/2.0/IGnss.h>
@@ -34,6 +35,7 @@
             const bool enableCorrVecOutputs);
     static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
     static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+    static aidl::android::hardware::gnss::GnssLocation getMockLocation();
     static V2_0::GnssLocation getMockLocationV2_0();
     static V1_0::GnssLocation getMockLocationV1_0();
     static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 9c84e80..be22ff6 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -24,12 +24,10 @@
 namespace gnss {
 namespace common {
 
-using GnssConstellationType_V1_0 = V1_0::GnssConstellationType;
-using GnssConstellationType_V2_0 = V2_0::GnssConstellationType;
-
+using namespace measurement_corrections::V1_0;
 using V1_0::GnssLocationFlags;
 
-void Utils::checkLocation(const GnssLocation& location, bool check_speed,
+void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
                           bool check_more_accuracies) {
     EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
     EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
@@ -96,7 +94,7 @@
     EXPECT_GT(location.timestamp, 1.48e12);
 }
 
-const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
+const MeasurementCorrections Utils::getMockMeasurementCorrections() {
     ReflectingPlane reflectingPlane = {
             .latitudeDegrees = 37.4220039,
             .longitudeDegrees = -122.0840991,
@@ -104,12 +102,12 @@
             .azimuthDegrees = 203.0,
     };
 
-    SingleSatCorrection_V1_0 singleSatCorrection1 = {
+    SingleSatCorrection singleSatCorrection1 = {
             .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC |
                                         GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE,
-            .constellation = GnssConstellationType_V1_0::GPS,
+            .constellation = V1_0::GnssConstellationType::GPS,
             .svid = 12,
             .carrierFrequencyHz = 1.59975e+09,
             .probSatIsLos = 0.50001,
@@ -117,11 +115,11 @@
             .excessPathLengthUncertaintyMeters = 25.5,
             .reflectingPlane = reflectingPlane,
     };
-    SingleSatCorrection_V1_0 singleSatCorrection2 = {
+    SingleSatCorrection singleSatCorrection2 = {
             .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC,
-            .constellation = GnssConstellationType_V1_0::GPS,
+            .constellation = V1_0::GnssConstellationType::GPS,
             .svid = 9,
             .carrierFrequencyHz = 1.59975e+09,
             .probSatIsLos = 0.873,
@@ -129,9 +127,9 @@
             .excessPathLengthUncertaintyMeters = 10.0,
     };
 
-    hidl_vec<SingleSatCorrection_V1_0> singleSatCorrections = {singleSatCorrection1,
-                                                               singleSatCorrection2};
-    MeasurementCorrections_1_0 mockCorrections = {
+    hidl_vec<SingleSatCorrection> singleSatCorrections = {singleSatCorrection1,
+                                                          singleSatCorrection2};
+    MeasurementCorrections mockCorrections = {
             .latitudeDegrees = 37.4219999,
             .longitudeDegrees = -122.0840575,
             .altitudeMeters = 30.60062531,
@@ -143,25 +141,26 @@
     return mockCorrections;
 }
 
-const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
-    MeasurementCorrections_1_0 mockCorrections_1_0 = getMockMeasurementCorrections();
+const measurement_corrections::V1_1::MeasurementCorrections
+Utils::getMockMeasurementCorrections_1_1() {
+    MeasurementCorrections mockCorrections_1_0 = getMockMeasurementCorrections();
 
-    SingleSatCorrection_V1_1 singleSatCorrection1 = {
+    measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection1 = {
             .v1_0 = mockCorrections_1_0.satCorrections[0],
-            .constellation = GnssConstellationType_V2_0::IRNSS,
+            .constellation = V2_0::GnssConstellationType::IRNSS,
     };
-    SingleSatCorrection_V1_1 singleSatCorrection2 = {
+    measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection2 = {
             .v1_0 = mockCorrections_1_0.satCorrections[1],
-            .constellation = GnssConstellationType_V2_0::IRNSS,
+            .constellation = V2_0::GnssConstellationType::IRNSS,
     };
 
-    mockCorrections_1_0.satCorrections[0].constellation = GnssConstellationType_V1_0::UNKNOWN;
-    mockCorrections_1_0.satCorrections[1].constellation = GnssConstellationType_V1_0::UNKNOWN;
+    mockCorrections_1_0.satCorrections[0].constellation = V1_0::GnssConstellationType::UNKNOWN;
+    mockCorrections_1_0.satCorrections[1].constellation = V1_0::GnssConstellationType::UNKNOWN;
 
-    hidl_vec<SingleSatCorrection_V1_1> singleSatCorrections = {singleSatCorrection1,
-                                                               singleSatCorrection2};
+    hidl_vec<measurement_corrections::V1_1::SingleSatCorrection> singleSatCorrections = {
+            singleSatCorrection1, singleSatCorrection2};
 
-    MeasurementCorrections_1_1 mockCorrections_1_1 = {
+    measurement_corrections::V1_1::MeasurementCorrections mockCorrections_1_1 = {
             .v1_0 = mockCorrections_1_0,
             .hasEnvironmentBearing = true,
             .environmentBearingDegrees = 45.0,
@@ -177,22 +176,22 @@
  * GnssConstellationType_1_0 type constellation. For constellations that do not have
  * an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
  */
-GnssConstellationType_1_0 Utils::mapConstellationType(GnssConstellationType_2_0 constellation) {
+V1_0::GnssConstellationType Utils::mapConstellationType(V2_0::GnssConstellationType constellation) {
     switch (constellation) {
-        case GnssConstellationType_2_0::GPS:
-            return GnssConstellationType_1_0::GPS;
-        case GnssConstellationType_2_0::SBAS:
-            return GnssConstellationType_1_0::SBAS;
-        case GnssConstellationType_2_0::GLONASS:
-            return GnssConstellationType_1_0::GLONASS;
-        case GnssConstellationType_2_0::QZSS:
-            return GnssConstellationType_1_0::QZSS;
-        case GnssConstellationType_2_0::BEIDOU:
-            return GnssConstellationType_1_0::BEIDOU;
-        case GnssConstellationType_2_0::GALILEO:
-            return GnssConstellationType_1_0::GALILEO;
+        case V2_0::GnssConstellationType::GPS:
+            return V1_0::GnssConstellationType::GPS;
+        case V2_0::GnssConstellationType::SBAS:
+            return V1_0::GnssConstellationType::SBAS;
+        case V2_0::GnssConstellationType::GLONASS:
+            return V1_0::GnssConstellationType::GLONASS;
+        case V2_0::GnssConstellationType::QZSS:
+            return V1_0::GnssConstellationType::QZSS;
+        case V2_0::GnssConstellationType::BEIDOU:
+            return V1_0::GnssConstellationType::BEIDOU;
+        case V2_0::GnssConstellationType::GALILEO:
+            return V1_0::GnssConstellationType::GALILEO;
         default:
-            return GnssConstellationType_1_0::UNKNOWN;
+            return V1_0::GnssConstellationType::UNKNOWN;
     }
 }
 
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index a4aad80..91c1167 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -22,33 +22,21 @@
 #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
 #include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
 
-using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
-using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
-using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
-using namespace android::hardware::gnss::measurement_corrections::V1_0;
-
-using MeasurementCorrections_1_0 =
-        android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
-using MeasurementCorrections_1_1 =
-        android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
-
-using SingleSatCorrection_V1_0 =
-        android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
-using SingleSatCorrection_V1_1 =
-        android::hardware::gnss::measurement_corrections::V1_1::SingleSatCorrection;
-
 namespace android {
 namespace hardware {
 namespace gnss {
 namespace common {
 
 struct Utils {
-    static void checkLocation(const GnssLocation& location, bool check_speed,
+    static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
                               bool check_more_accuracies);
-    static const MeasurementCorrections_1_0 getMockMeasurementCorrections();
-    static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
+    static const measurement_corrections::V1_0::MeasurementCorrections
+    getMockMeasurementCorrections();
+    static const measurement_corrections::V1_1::MeasurementCorrections
+    getMockMeasurementCorrections_1_1();
 
-    static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
+    static V1_0::GnssConstellationType mapConstellationType(
+            V2_0::GnssConstellationType constellation);
 
     static bool isAutomotiveDevice();
 };
diff --git a/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h b/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
index 33012e9..18a50fe 100644
--- a/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
+++ b/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
@@ -29,6 +29,8 @@
 namespace V2_2 {
 namespace hal {
 
+using V2_1::Display;
+using V2_1::Error;
 using V2_1::hal::ComposerHandleCache;
 using V2_1::hal::ComposerHandleImporter;
 
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 5c085cb..51295a6 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -43,6 +43,7 @@
         "libmath",
         "libnativewindow",
         "librenderengine",
+        "libtonemap",
         "android.hardware.graphics.mapper@3.0",
         "android.hardware.graphics.mapper@3.0-vts",
         "android.hardware.graphics.mapper@4.0",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 36f3c00..79ed368 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -67,6 +67,7 @@
         "android.hardware.graphics.mapper@4.0-vts",
         "libgtest",
         "librenderengine",
+        "libtonemap",
     ],
     header_libs: [
         "android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index 5c37018..d7cab2b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -85,4 +85,5 @@
   const int EX_UNSUPPORTED = 8;
   const int EX_SEAMLESS_NOT_ALLOWED = 9;
   const int EX_SEAMLESS_NOT_POSSIBLE = 10;
+  const int INVALID_CONFIGURATION = 2147483647;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 2a9545d..230980d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -90,6 +90,12 @@
     const int EX_SEAMLESS_NOT_POSSIBLE = 10;
 
     /**
+     * Integer.MAX_VALUE is reserved for the invalid configuration.
+     * This should not be returned as a valid configuration.
+     */
+    const int INVALID_CONFIGURATION = 0x7fffffff;
+
+    /**
      * Creates a new layer on the given display.
      *
      * @param display is the display on which to create the layer.
@@ -282,6 +288,7 @@
     /**
      * Returns handles for all of the valid display configurations on this
      * display.
+     * This should never return INVALID_CONFIGURATION as a valid value.
      *
      * @param display is the display to query.
      *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 420b32c..c011f73 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -32,12 +32,27 @@
     srcs: [
         "VtsHalGraphicsComposer3_TargetTest.cpp",
         "composer-vts/GraphicsComposerCallback.cpp",
+        "composer-vts/TestCommandReader.cpp",
     ],
 
-    // TODO(b/64437680): Assume these libs are always available on the device.
     shared_libs: [
         "libbinder_ndk",
         "libbinder",
+        "libfmq",
+        "libbase",
+        "libsync",
+        "libui",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
+        "libvndksupport",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
@@ -45,9 +60,19 @@
         "android.hardware.graphics.common@1.2",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
         "android.hardware.graphics.composer@3-vts",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@2.1-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+        "libaidlcommonsupport",
     ],
-
+    cflags: [
+        "-Wconversion",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index 2dc80fc..9ea837e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1,22 +1,40 @@
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/command-buffer.h>
 #include <binder/ProcessState.h>
-#include <composer-vts/include/GraphicsComposerCallback.h>
 #include <gtest/gtest.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <algorithm>
+#include <numeric>
+#include <regex>
 #include <string>
 #include <thread>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include "composer-vts/include/GraphicsComposerCallback.h"
+#include "composer-vts/include/TestCommandReader.h"
 
-#pragma push_macro("LOG_TAG")
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 #undef LOG_TAG
 #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
 
-typedef int32_t Config;
-
 namespace aidl::android::hardware::graphics::composer3::vts {
 namespace {
 
@@ -29,6 +47,12 @@
 
     int64_t get() const { return mDisplayId; }
 
+    FRect getCrop() const {
+        return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
+    }
+
+    Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+
     void setDimensions(int32_t displayWidth, int32_t displayHeight) {
         mDisplayWidth = displayWidth;
         mDisplayHeight = displayHeight;
@@ -56,13 +80,36 @@
 
         // assume the first displays are built-in and are never removed
         mDisplays = waitForDisplays();
+
+        // explicitly disable vsync
+        for (const auto& display : mDisplays) {
+            EXPECT_TRUE(mComposerClient->setVsyncEnabled(display.get(), false).isOk());
+        }
+        mComposerCallback->setVsyncAllowed(false);
+
+        mWriter = std::make_unique<CommandWriterBase>(1024);
+        mReader = std::make_unique<TestCommandReader>();
+    }
+
+    void TearDown() override {
+        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncPeriodChangeCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidSeamlessPossibleCount());
+        }
     }
 
     // returns an invalid display id (one that has not been registered to a
     // display.  Currently assuming that a device will never have close to
     // std::numeric_limit<uint64_t>::max() displays registered while running tests
-    uint64_t GetInvalidDisplayId() {
-        uint64_t id = std::numeric_limits<uint64_t>::max();
+    int64_t GetInvalidDisplayId() {
+        int64_t id = std::numeric_limits<int64_t>::max();
         while (id > 0) {
             if (std::none_of(mDisplays.begin(), mDisplays.end(),
                              [&](const VtsDisplay& display) { return id == display.get(); })) {
@@ -87,7 +134,7 @@
             std::vector<VtsDisplay> vtsDisplays;
             vtsDisplays.reserve(displays.size());
             for (int64_t display : displays) {
-                Config activeConfig;
+                int32_t activeConfig;
                 EXPECT_TRUE(mComposerClient->getActiveConfig(display, &activeConfig).isOk());
                 int32_t displayWidth;
                 EXPECT_TRUE(mComposerClient
@@ -106,11 +153,364 @@
         }
     }
 
+    // returns an invalid config id which is std::numeric_limit<int32_t>::max()
+    int32_t GetInvalidConfigId() { return IComposerClient::INVALID_CONFIGURATION; }
+
+    ndk::ScopedAStatus setActiveConfigWithConstraints(
+            VtsDisplay& display, int32_t config, const VsyncPeriodChangeConstraints& constraints,
+            VsyncPeriodChangeTimeline* timeline) {
+        auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config,
+                                                                     constraints, timeline);
+        if (error.isOk()) {
+            int32_t displayWidth;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::WIDTH, &displayWidth)
+                                .isOk());
+            int32_t displayHeight;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::HEIGHT, &displayHeight)
+                                .isOk());
+            display.setDimensions(displayWidth, displayHeight);
+        }
+        return error;
+    }
+
+    void Test_setContentTypeForDisplay(const int64_t& display,
+                                       const std::vector<ContentType>& capabilities,
+                                       const ContentType& contentType, const char* contentTypeStr) {
+        const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
+                                                  contentType) != capabilities.end();
+
+        if (!contentTypeSupport) {
+            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
+                      mComposerClient->setContentType(display, contentType)
+                              .getServiceSpecificError());
+            GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
+                            << std::to_string(display) << ", skipping test";
+            return;
+        }
+
+        EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
+        EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
+    }
+
+    void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
+        for (const auto& display : mDisplays) {
+            std::vector<ContentType> supportedContentTypes;
+            const auto error = mComposerClient->getSupportedContentTypes(display.get(),
+                                                                         &supportedContentTypes);
+            EXPECT_TRUE(error.isOk());
+
+            Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
+                                          contentTypeStr);
+        }
+    }
+
+    void execute() {
+        TestCommandReader* reader = mReader.get();
+        CommandWriterBase* writer = mWriter.get();
+        bool queueChanged = false;
+        int32_t commandLength = 0;
+        std::vector<NativeHandle> commandHandles;
+        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+        if (queueChanged) {
+            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
+            ASSERT_TRUE(ret.isOk());
+        }
+
+        ExecuteCommandsStatus commandStatus;
+        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
+                            .isOk());
+
+        if (commandStatus.queueChanged) {
+            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
+            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
+            reader->setMQDescriptor(outputCommandQueue);
+        }
+        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
+        reader->parse();
+        reader->reset();
+        writer->reset();
+    }
+
+    ::android::sp<::android::GraphicBuffer> allocate(uint32_t width, uint32_t height) {
+        ::android::sp<::android::GraphicBuffer> buffer =
+                ::android::sp<::android::GraphicBuffer>::make(
+                        width, height, ::android::PIXEL_FORMAT_RGBA_8888,
+                        /*layerCount*/ 1,
+                        static_cast<uint64_t>(
+                                static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                                static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
+                        "VtsHalGraphicsComposer3_TargetTest");
+
+        return buffer;
+    }
+
+    struct TestParameters {
+        nsecs_t delayForChange;
+        bool refreshMiss;
+    };
+
+    static inline auto toTimePoint(nsecs_t time) {
+        return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
+    }
+
+    int64_t createLayer(const VtsDisplay& display) {
+        int64_t layer;
+        EXPECT_TRUE(mComposerClient->createLayer(display.get(), kBufferSlotCount, &layer).isOk());
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        if (resourceIt == mDisplayResources.end()) {
+            resourceIt = mDisplayResources.insert({display.get(), DisplayResource(false)}).first;
+        }
+
+        EXPECT_TRUE(resourceIt->second.layers.insert(layer).second)
+                << "duplicated layer id " << layer;
+
+        return layer;
+    }
+
+    void destroyLayer(const VtsDisplay& display, int64_t layer) {
+        auto const error = mComposerClient->destroyLayer(display.get(), layer);
+        ASSERT_TRUE(error.isOk()) << "failed to destroy layer " << layer;
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        ASSERT_NE(mDisplayResources.end(), resourceIt);
+        resourceIt->second.layers.erase(layer);
+    }
+
+    void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
+        std::vector<int32_t> displayConfigs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display, &displayConfigs).isOk());
+        for (const int32_t config1 : displayConfigs) {
+            for (const int32_t config2 : displayConfigs) {
+                if (config1 != config2) {
+                    func(config1, config2);
+                }
+            }
+        }
+    }
+
+    void setActiveConfig(VtsDisplay& display, int32_t config) {
+        EXPECT_TRUE(mComposerClient->setActiveConfig(display.get(), config).isOk());
+        int32_t displayWidth;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH,
+                                                  &displayWidth)
+                            .isOk());
+        int32_t displayHeight;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT,
+                                                  &displayHeight)
+                            .isOk());
+        display.setDimensions(displayWidth, displayHeight);
+    }
+
+    void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
+        if (timeline != nullptr) {
+            // Refresh time should be before newVsyncAppliedTimeNanos
+            EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
+
+            std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
+        }
+
+        mWriter->selectDisplay(display.get());
+        setPowerMode(display.get(), PowerMode::ON);
+        EXPECT_TRUE(
+                mComposerClient
+                        ->setColorMode(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC)
+                        .isOk());
+
+        FRect displayCrop = display.getCrop();
+        auto displayWidth = static_cast<uint32_t>(std::ceilf(displayCrop.right - displayCrop.left));
+        auto displayHeight =
+                static_cast<uint32_t>(std::ceilf(displayCrop.bottom - displayCrop.top));
+        int64_t layer = 0;
+        ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
+        {
+            auto buffer = allocate(displayWidth, displayHeight);
+            ASSERT_NE(nullptr, buffer);
+            ASSERT_EQ(::android::OK, buffer->initCheck());
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter->selectLayer(layer);
+            mWriter->setLayerCompositionType(Composition::DEVICE);
+            mWriter->setLayerDisplayFrame(display.getFrameRect());
+            mWriter->setLayerPlaneAlpha(1);
+            mWriter->setLayerSourceCrop(display.getCrop());
+            mWriter->setLayerTransform(static_cast<Transform>(0));
+            mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
+            mWriter->setLayerZOrder(10);
+            mWriter->setLayerBlendMode(BlendMode::NONE);
+            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
+            mWriter->setLayerBuffer(0, buffer->handle, -1);
+            mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+
+            mWriter->validateDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+            mReader->mCompositionChanges.clear();
+
+            mWriter->presentDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+        }
+
+        {
+            auto buffer = allocate(displayWidth, displayHeight);
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter->selectLayer(layer);
+            mWriter->setLayerBuffer(0, buffer->handle, -1);
+            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
+            mWriter->validateDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+            mReader->mCompositionChanges.clear();
+
+            mWriter->presentDisplay();
+            execute();
+        }
+
+        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
+    }
+
+    void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
+                                  int64_t desiredTimeNanos, int64_t oldPeriodNanos,
+                                  int64_t newPeriodNanos) {
+        const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
+        while (std::chrono::steady_clock::now() <= kChangeDeadline) {
+            int32_t vsyncPeriodNanos;
+            EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos).isOk());
+            if (systemTime() <= desiredTimeNanos) {
+                EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
+            } else if (vsyncPeriodNanos == newPeriodNanos) {
+                break;
+            }
+            std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
+        }
+    }
+
+    void Test_setActiveConfigWithConstraints(const TestParameters& params) {
+        for (VtsDisplay& display : mDisplays) {
+            forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+
+                int32_t vsyncPeriod1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod1)
+                                    .isOk());
+                int32_t configGroup1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup1)
+                                    .isOk());
+                int32_t vsyncPeriod2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod2)
+                                    .isOk());
+                int32_t configGroup2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup2)
+                                    .isOk());
+
+                if (vsyncPeriod1 == vsyncPeriod2) {
+                    return;  // continue
+                }
+
+                // We don't allow delayed change when changing config groups
+                if (params.delayForChange > 0 && configGroup1 != configGroup2) {
+                    return;  // continue
+                }
+
+                VsyncPeriodChangeTimeline timeline;
+                VsyncPeriodChangeConstraints constraints = {
+                        .desiredTimeNanos = systemTime() + params.delayForChange,
+                        .seamlessRequired = false};
+                EXPECT_TRUE(setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                    .isOk());
+
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+                // Refresh rate should change within a reasonable time
+                constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s;  // 1 second
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+                            kReasonableTimeForChange.count());
+
+                if (timeline.refreshRequired) {
+                    if (params.refreshMiss) {
+                        // Miss the refresh frame on purpose to make sure the implementation sends a
+                        // callback
+                        std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
+                                                      100ms);
+                    }
+                    sendRefreshFrame(display, &timeline);
+                }
+                waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
+                                         vsyncPeriod1, vsyncPeriod2);
+
+                // At this point the refresh rate should have changed already, however in rare
+                // cases the implementation might have missed the deadline. In this case a new
+                // timeline should have been provided.
+                auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+                if (timeline.refreshRequired && params.refreshMiss) {
+                    EXPECT_TRUE(newTimeline.has_value());
+                }
+
+                if (newTimeline.has_value()) {
+                    if (newTimeline->refreshRequired) {
+                        sendRefreshFrame(display, &newTimeline.value());
+                    }
+                    waitForVsyncPeriodChange(display.get(), newTimeline.value(),
+                                             constraints.desiredTimeNanos, vsyncPeriod1,
+                                             vsyncPeriod2);
+                }
+
+                int32_t vsyncPeriodNanos;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
+            });
+        }
+    }
+
+    void setPowerMode(int64_t display, PowerMode powerMode) {
+        ::ndk::ScopedAStatus error = mComposerClient->setPowerMode(display, powerMode);
+        ASSERT_TRUE(error.isOk() ||
+                    IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+                << "failed to set power mode";
+    }
+
+    // Keep track of all virtual displays and layers.  When a test fails with
+    // ASSERT_*, the destructor will clean up the resources for the test.
+    struct DisplayResource {
+        DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
+
+        bool isVirtual;
+        std::unordered_set<int64_t> layers;
+    };
+
     std::shared_ptr<IComposer> mComposer;
     std::shared_ptr<IComposerClient> mComposerClient;
     int64_t mInvalidDisplayId;
+    int64_t mPrimaryDisplay;
     std::vector<VtsDisplay> mDisplays;
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+    std::unique_ptr<CommandWriterBase> mWriter;
+    std::unique_ptr<TestCommandReader> mReader;
+    // use the slot count usually set by SF
+    static constexpr uint32_t kBufferSlotCount = 64;
+    std::unordered_map<int64_t, DisplayResource> mDisplayResources;
 };
 
 TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBadDisplay) {
@@ -129,6 +529,778 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod) {
+    for (VtsDisplay& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+        for (int32_t config : configs) {
+            int32_t expectedVsyncPeriodNanos = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::VSYNC_PERIOD,
+                                                      &expectedVsyncPeriodNanos)
+                                .isOk());
+
+            VsyncPeriodChangeTimeline timeline;
+            VsyncPeriodChangeConstraints constraints;
+
+            constraints.desiredTimeNanos = systemTime();
+            constraints.seamlessRequired = false;
+            EXPECT_TRUE(mComposerClient
+                                ->setActiveConfigWithConstraints(display.get(), config, constraints,
+                                                                 &timeline)
+                                .isOk());
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(display, &timeline);
+            }
+            waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
+                                     expectedVsyncPeriodNanos);
+
+            int32_t vsyncPeriodNanos;
+            int retryCount = 100;
+            do {
+                std::this_thread::sleep_for(10ms);
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                --retryCount;
+            } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
+
+            EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+            // Make sure that the vsync period stays the same if the active config is not
+            // changed.
+            auto timeout = 1ms;
+            for (int i = 0; i < 10; i++) {
+                std::this_thread::sleep_for(timeout);
+                timeout *= 2;
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+    VsyncPeriodChangeTimeline timeline;
+    VsyncPeriodChangeConstraints constraints;
+
+    constraints.seamlessRequired = true;
+    constraints.desiredTimeNanos = systemTime();
+
+    for (VtsDisplay& display : mDisplays) {
+        forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+            int32_t configGroup1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config1,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup1)
+                                .isOk());
+            int32_t configGroup2;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config2,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup2)
+                                .isOk());
+            if (configGroup1 != configGroup2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+                EXPECT_EQ(IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
+                          setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                  .getServiceSpecificError());
+            }
+        });
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints) {
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
+}
+TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
+    DisplayIdentification displayIdentification0;
+
+    const auto error =
+            mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification0);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        return;
+    }
+    ASSERT_TRUE(error.isOk()) << "failed to get display identification data";
+    ASSERT_FALSE(displayIdentification0.data.empty());
+
+    constexpr size_t kEdidBlockSize = 128;
+    ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
+            << "EDID blob length is not a multiple of " << kEdidBlockSize;
+
+    const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+    ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
+                           displayIdentification0.data.begin()))
+            << "EDID blob doesn't start with the fixed EDID header";
+    ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
+                                 displayIdentification0.data.begin() + kEdidBlockSize,
+                                 static_cast<uint8_t>(0)))
+            << "EDID base block doesn't checksum";
+
+    DisplayIdentification displayIdentification1;
+    ASSERT_TRUE(
+            mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification1)
+                    .isOk());
+
+    ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
+    ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
+                std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
+                           displayIdentification1.data.begin()))
+            << "data is not stable";
+}
+
+TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
+    HdrCapabilities hdrCapabilities;
+    const auto error = mComposerClient->getHdrCapabilities(mPrimaryDisplay, &hdrCapabilities);
+
+    ASSERT_TRUE(error.isOk());
+    ASSERT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
+    std::vector<PerFrameMetadataKey> keys;
+    const auto error = mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay, &keys);
+
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
+        return;
+    }
+    EXPECT_TRUE(error.isOk());
+    ASSERT_TRUE(keys.size() >= 0);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
+    ReadbackBufferAttributes readBackBufferAttributes;
+    const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+                                                                    &readBackBufferAttributes);
+
+    if (error.isOk()) {
+        EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
+    std::vector<ColorMode> modes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+    for (auto mode : modes) {
+        std::vector<RenderIntent> intents;
+        EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk());
+
+        bool isHdr;
+        switch (mode) {
+            case ColorMode::BT2100_PQ:
+            case ColorMode::BT2100_HLG:
+                isHdr = true;
+                break;
+            default:
+                isHdr = false;
+                break;
+        }
+        RenderIntent requiredIntent =
+                isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
+
+        auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
+        EXPECT_NE(intents.cend(), iter);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadDisplay) {
+    std::vector<ColorMode> modes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+    for (auto mode : modes) {
+        std::vector<RenderIntent> renderIntents;
+        const auto error =
+                mComposerClient->getRenderIntents(mInvalidDisplayId, mode, &renderIntents);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadParameter) {
+    std::vector<RenderIntent> renderIntents;
+    const auto error = mComposerClient->getRenderIntents(
+            mPrimaryDisplay, static_cast<ColorMode>(-1), &renderIntents);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModes) {
+    std::vector<ColorMode> colorModes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+
+    auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
+    ASSERT_NE(colorModes.cend(), native);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModeBadDisplay) {
+    std::vector<ColorMode> colorModes;
+    const auto error = mComposerClient->getColorModes(mInvalidDisplayId, &colorModes);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorMode) {
+    std::vector<ColorMode> colorModes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+    for (auto mode : colorModes) {
+        std::vector<RenderIntent> intents;
+        EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk())
+                << "failed to get render intents";
+        for (auto intent : intents) {
+            const auto error = mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
+            EXPECT_TRUE(error.isOk() ||
+                        IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+                    << "failed to set color mode";
+        }
+    }
+
+    const auto error = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+                                                     RenderIntent::COLORIMETRIC);
+    EXPECT_TRUE(error.isOk() || IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+            << "failed to set color mode";
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadDisplay) {
+    auto const error = mComposerClient->setColorMode(mInvalidDisplayId, ColorMode::NATIVE,
+                                                     RenderIntent::COLORIMETRIC);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadParameter) {
+    const auto colorModeError = mComposerClient->setColorMode(
+            mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
+
+    EXPECT_FALSE(colorModeError.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, colorModeError.getServiceSpecificError());
+
+    const auto renderIntentError = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+                                                                 static_cast<RenderIntent>(-1));
+
+    EXPECT_FALSE(renderIntentError.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, renderIntentError.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
+    int constexpr invalid = -1;
+
+    DisplayContentSamplingAttributes format;
+    auto error = mComposerClient->getDisplayedContentSamplingAttributes(mPrimaryDisplay, &format);
+
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_NE(format.format, static_cast<common::PixelFormat>(invalid));
+    EXPECT_NE(format.dataspace, static_cast<common::Dataspace>(invalid));
+    EXPECT_NE(format.componentMask, static_cast<FormatColorComponent>(invalid));
+};
+
+TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
+    auto const maxFrames = 10;
+    FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
+    auto error = mComposerClient->setDisplayedContentSamplingEnabled(
+            mPrimaryDisplay, true, enableAllComponents, maxFrames);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+    EXPECT_TRUE(error.isOk());
+
+    error = mComposerClient->setDisplayedContentSamplingEnabled(mPrimaryDisplay, false,
+                                                                enableAllComponents, maxFrames);
+    EXPECT_TRUE(error.isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
+    DisplayContentSamplingAttributes displayContentSamplingAttributes;
+    int constexpr invalid = -1;
+    displayContentSamplingAttributes.format = static_cast<common::PixelFormat>(invalid);
+    displayContentSamplingAttributes.dataspace = static_cast<common::Dataspace>(invalid);
+    displayContentSamplingAttributes.componentMask = static_cast<FormatColorComponent>(invalid);
+    EXPECT_TRUE(mComposerClient
+                        ->getDisplayedContentSamplingAttributes(mPrimaryDisplay,
+                                                                &displayContentSamplingAttributes)
+                        .isOk());
+
+    int64_t maxFrames = 10;
+    int64_t timestamp = 0;
+    int64_t frameCount = 0;
+    DisplayContentSample displayContentSample;
+    auto error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
+                                                            &displayContentSample);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_LE(frameCount, maxFrames);
+    std::vector<std::vector<int64_t>> histogram = {
+            displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
+            displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
+
+    for (size_t i = 0; i < histogram.size(); i++) {
+        const bool shouldHaveHistogram =
+                static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
+        EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBasic) {
+    std::vector<DisplayCapability> capabilities;
+    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    const bool hasDozeSupport = std::find(capabilities.begin(), capabilities.end(),
+                                          DisplayCapability::DOZE) != capabilities.end();
+    bool isDozeSupported = false;
+    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    EXPECT_EQ(hasDozeSupport, isDozeSupported);
+
+    bool hasBrightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+                                          DisplayCapability::BRIGHTNESS) != capabilities.end();
+    bool isBrightnessSupported = false;
+    EXPECT_TRUE(
+            mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay, &isBrightnessSupported)
+                    .isOk());
+    EXPECT_EQ(isBrightnessSupported, hasBrightnessSupport);
+}
+
+/*
+ * Test that if brightness operations are supported, setDisplayBrightness works as expected.
+ */
+TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) {
+    std::vector<DisplayCapability> capabilities;
+    auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+                                       DisplayCapability::BRIGHTNESS) != capabilities.end();
+    if (!brightnessSupport) {
+        EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f)
+                          .getServiceSpecificError(),
+                  IComposerClient::EX_UNSUPPORTED);
+        GTEST_SUCCEED() << "Brightness operations are not supported";
+        return;
+    }
+
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk());
+
+    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+
+    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) {
+    DisplayConnectionType type;
+    EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk());
+    for (const auto& display : mDisplays) {
+        EXPECT_TRUE(mComposerClient->getDisplayConnectionType(display.get(), &type).isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) {
+    for (const auto& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+        for (const auto& config : configs) {
+            const std::array<DisplayAttribute, 4> requiredAttributes = {{
+                    DisplayAttribute::WIDTH,
+                    DisplayAttribute::HEIGHT,
+                    DisplayAttribute::VSYNC_PERIOD,
+                    DisplayAttribute::CONFIG_GROUP,
+            }};
+            int32_t value;
+            for (const auto& attribute : requiredAttributes) {
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config, attribute, &value)
+                                    .isOk());
+                EXPECT_NE(-1, value);
+            }
+
+            const std::array<DisplayAttribute, 2> optionalAttributes = {{
+                    DisplayAttribute::DPI_X,
+                    DisplayAttribute::DPI_Y,
+            }};
+            for (const auto& attribute : optionalAttributes) {
+                const auto error = mComposerClient->getDisplayAttribute(display.get(), config,
+                                                                        attribute, &value);
+                if (error.isOk()) {
+                    EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+                } else {
+                    EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+                }
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) {
+    for (const auto& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+
+        EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
+            return config == IComposerClient::INVALID_CONFIGURATION;
+        }));
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayAttributeConfigsInAGroupDifferOnlyByVsyncPeriod) {
+    struct Resolution {
+        int32_t width;
+        int32_t height;
+    };
+    struct Dpi {
+        int32_t x;
+        int32_t y;
+    };
+    for (const auto& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+        std::unordered_map<int32_t, Resolution> configGroupToResolutionMap;
+        std::unordered_map<int32_t, Dpi> configGroupToDpiMap;
+        for (const auto& config : configs) {
+            int32_t configGroup = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup)
+                                .isOk());
+            int32_t width = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::WIDTH, &width)
+                                .isOk());
+            int32_t height = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::HEIGHT, &height)
+                                .isOk());
+            if (configGroupToResolutionMap.find(configGroup) == configGroupToResolutionMap.end()) {
+                configGroupToResolutionMap[configGroup] = {width, height};
+            }
+            EXPECT_EQ(configGroupToResolutionMap[configGroup].width, width);
+            EXPECT_EQ(configGroupToResolutionMap[configGroup].height, height);
+
+            int32_t dpiX = -1;
+            mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_X,
+                                                 &dpiX);
+
+            int32_t dpiY = -1;
+            mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_Y,
+                                                 &dpiY);
+            if (dpiX == -1 && dpiY == -1) {
+                continue;
+            }
+
+            if (configGroupToDpiMap.find(configGroup) == configGroupToDpiMap.end()) {
+                configGroupToDpiMap[configGroup] = {dpiX, dpiY};
+            }
+            EXPECT_EQ(configGroupToDpiMap[configGroup].x, dpiX);
+            EXPECT_EQ(configGroupToDpiMap[configGroup].y, dpiY);
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod_BadDisplay) {
+    int32_t vsyncPeriodNanos;
+    const auto error = mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadDisplay) {
+    VsyncPeriodChangeTimeline timeline;
+    VsyncPeriodChangeConstraints constraints;
+
+    constraints.seamlessRequired = false;
+    constraints.desiredTimeNanos = systemTime();
+    int32_t config = 0;
+    auto const error = mComposerClient->setActiveConfigWithConstraints(mInvalidDisplayId, config,
+                                                                       constraints, &timeline);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) {
+    VsyncPeriodChangeTimeline timeline;
+    VsyncPeriodChangeConstraints constraints;
+
+    constraints.seamlessRequired = false;
+    constraints.desiredTimeNanos = systemTime();
+
+    for (VtsDisplay& display : mDisplays) {
+        int32_t invalidConfigId = GetInvalidConfigId();
+        const auto error =
+                setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) {
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY,
+              mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true)
+                      .getServiceSpecificError());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY,
+              mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false)
+                      .getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyMode) {
+    for (const auto& display : mDisplays) {
+        std::vector<DisplayCapability> capabilities;
+        const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities);
+        EXPECT_TRUE(error.isOk());
+
+        const bool allmSupport =
+                std::find(capabilities.begin(), capabilities.end(),
+                          DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
+
+        if (!allmSupport) {
+            const auto errorIsOn = mComposerClient->setAutoLowLatencyMode(display.get(), true);
+            EXPECT_FALSE(errorIsOn.isOk());
+            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOn.getServiceSpecificError());
+            const auto errorIsOff = mComposerClient->setAutoLowLatencyMode(display.get(), false);
+            EXPECT_FALSE(errorIsOff.isOk());
+            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOff.getServiceSpecificError());
+            GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
+                            << std::to_string(display.get()) << ", skipping test";
+            return;
+        }
+
+        EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), true).isOk());
+        EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), false).isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getSupportedContentTypesBadDisplay) {
+    std::vector<ContentType> supportedContentTypes;
+    const auto error =
+            mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, getSupportedContentTypes) {
+    std::vector<ContentType> supportedContentTypes;
+    for (const auto& display : mDisplays) {
+        supportedContentTypes.clear();
+        const auto error =
+                mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
+
+        ASSERT_TRUE(error.isOk());
+
+        const bool noneSupported =
+                std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
+                          ContentType::NONE) != supportedContentTypes.end();
+        EXPECT_FALSE(noneSupported);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setContentTypeNoneAlwaysAccepted) {
+    for (const auto& display : mDisplays) {
+        const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE);
+        EXPECT_TRUE(error.isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setContentTypeBadDisplay) {
+    constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
+                                     ContentType::CINEMA, ContentType::GAME};
+    for (const auto& type : types) {
+        auto const error = mComposerClient->setContentType(mInvalidDisplayId, type);
+
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setGraphicsContentType) {
+    Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
+}
+
+TEST_P(GraphicsComposerAidlTest, setPhotoContentType) {
+    Test_setContentType(ContentType::PHOTO, "PHOTO");
+}
+
+TEST_P(GraphicsComposerAidlTest, setCinemaContentType) {
+    Test_setContentType(ContentType::CINEMA, "CINEMA");
+}
+
+TEST_P(GraphicsComposerAidlTest, setGameContentType) {
+    Test_setContentType(ContentType::GAME, "GAME");
+}
+
+TEST_P(GraphicsComposerAidlTest, getLayerGenericMetadataKeys) {
+    std::vector<LayerGenericMetadataKey> keys;
+    EXPECT_TRUE(mComposerClient->getLayerGenericMetadataKeys(&keys).isOk());
+
+    std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
+    std::unordered_set<std::string> uniqueNames;
+    for (const auto& key : keys) {
+        std::string name(key.name);
+
+        // Keys must not start with 'android' or 'com.android'
+        EXPECT_FALSE(name.find("android") == 0);
+        EXPECT_FALSE(name.find("com.android") == 0);
+
+        // Keys must be in reverse domain name format
+        EXPECT_TRUE(std::regex_match(name, reverseDomainName));
+
+        // Keys must be unique within this list
+        const auto& [iter, inserted] = uniqueNames.insert(name);
+        EXPECT_TRUE(inserted);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
+    int32_t maxVirtualDisplayCount;
+    EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&maxVirtualDisplayCount).isOk());
+    if (maxVirtualDisplayCount == 0) {
+        GTEST_SUCCEED() << "no virtual display support";
+        return;
+    }
+
+    VirtualDisplay virtualDisplay;
+
+    EXPECT_TRUE(mComposerClient
+                        ->createVirtualDisplay(64, 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
+                                               kBufferSlotCount, &virtualDisplay)
+                        .isOk());
+
+    ASSERT_TRUE(mDisplayResources.insert({virtualDisplay.display, DisplayResource(true)}).second)
+            << "duplicated virtual display id " << virtualDisplay.display;
+
+    EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
+    std::vector<PowerMode> modes;
+    modes.push_back(PowerMode::OFF);
+    modes.push_back(PowerMode::ON_SUSPEND);
+    modes.push_back(PowerMode::ON);
+
+    for (auto mode : modes) {
+        setPowerMode(mPrimaryDisplay, mode);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
+    std::vector<PowerMode> modes;
+
+    modes.push_back(PowerMode::OFF);
+    modes.push_back(PowerMode::OFF);
+
+    for (auto mode : modes) {
+        setPowerMode(mPrimaryDisplay, mode);
+    }
+
+    modes.clear();
+
+    modes.push_back(PowerMode::ON);
+    modes.push_back(PowerMode::ON);
+
+    for (auto mode : modes) {
+        setPowerMode(mPrimaryDisplay, mode);
+    }
+
+    modes.clear();
+
+    modes.push_back(PowerMode::ON_SUSPEND);
+    modes.push_back(PowerMode::ON_SUSPEND);
+
+    for (auto mode : modes) {
+        setPowerMode(mPrimaryDisplay, mode);
+    }
+
+    bool isDozeSupported = false;
+    ASSERT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    if (isDozeSupported) {
+        modes.clear();
+
+        modes.push_back(PowerMode::DOZE);
+        modes.push_back(PowerMode::DOZE);
+
+        for (auto mode : modes) {
+            setPowerMode(mPrimaryDisplay, mode);
+        }
+
+        modes.clear();
+
+        modes.push_back(PowerMode::DOZE_SUSPEND);
+        modes.push_back(PowerMode::DOZE_SUSPEND);
+
+        for (auto mode : modes) {
+            setPowerMode(mPrimaryDisplay, mode);
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeBadDisplay) {
+    const auto error = mComposerClient->setPowerMode(mInvalidDisplayId, PowerMode::ON);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeBadParameter) {
+    const auto error = mComposerClient->setPowerMode(mPrimaryDisplay, static_cast<PowerMode>(-1));
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
+    bool isDozeSupported = false;
+    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    if (!isDozeSupported) {
+        auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+
+        error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE_SUSPEND);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
+    std::vector<float> matrix;
+    EXPECT_TRUE(
+            mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR, &matrix)
+                    .isOk());
+    // the last row is known
+    ASSERT_EQ(0.0f, matrix[12]);
+    ASSERT_EQ(0.0f, matrix[13]);
+    ASSERT_EQ(0.0f, matrix[14]);
+    ASSERT_EQ(1.0f, matrix[15]);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrixBadParameter) {
+    std::vector<float> matrix;
+    const auto error =
+            mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::UNKNOWN, &matrix);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlTest,
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index bb5f3f1..00ea4f3 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,17 +28,38 @@
     defaults: ["hidl_defaults"],
     srcs: [
         "GraphicsComposerCallback.cpp",
+        "TestCommandReader.cpp",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "libgtest",
         "libbase",
+        "libfmq",
+        "libsync",
+        "libaidlcommonsupport",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libhidlbase",
+        "android.hardware.graphics.composer3-V1-ndk",
     ],
     cflags: [
         "-O0",
         "-g",
         "-DLOG_TAG=\"ComposerVts\"",
+        "-Wconversion",
+    ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
new file mode 100644
index 0000000..0346686
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/TestCommandReader.h"
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+void TestCommandReader::parse() {
+    mErrors.clear();
+    mCompositionChanges.clear();
+    while (!isEmpty()) {
+        int32_t command;
+        uint16_t length;
+        ASSERT_TRUE(beginCommand(&command, &length));
+
+        parseSingleCommand(command, length);
+
+        endCommand();
+    }
+}
+
+void TestCommandReader::parseSingleCommand(int32_t commandRaw, uint16_t length) {
+    auto command = static_cast<Command>(commandRaw);
+
+    switch (command) {
+        case Command::SET_CLIENT_TARGET_PROPERTY:
+            ASSERT_EQ(2, length);
+            read();
+            close(readFence());
+            break;
+        case Command::SELECT_DISPLAY:
+            ASSERT_EQ(2, length);
+            read64();  // display
+            break;
+        case Command::SET_ERROR: {
+            ASSERT_EQ(2, length);
+            auto loc = read();
+            auto err = readSigned();
+            std::pair<uint32_t, uint32_t> error(loc, err);
+            mErrors.push_back(error);
+        } break;
+        case Command::SET_CHANGED_COMPOSITION_TYPES:
+            ASSERT_EQ(0, length % 3);
+            for (uint16_t count = 0; count < length / 3; ++count) {
+                uint64_t layerId = read64();
+                uint32_t composition = read();
+
+                std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
+                mCompositionChanges.push_back(compositionChange);
+            }
+            break;
+        case Command::SET_DISPLAY_REQUESTS:
+            ASSERT_EQ(1, length % 3);
+            read();  // displayRequests, ignored for now
+            for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
+                read64();  // layer
+                // silently eat requests to clear the client target, since we won't be testing
+                // client composition anyway
+                ASSERT_EQ(1u, read());
+            }
+            break;
+        case Command::SET_PRESENT_FENCE:
+            ASSERT_EQ(1, length);
+            close(readFence());
+            break;
+        case Command::SET_RELEASE_FENCES:
+            ASSERT_EQ(0, length % 3);
+            for (uint16_t count = 0; count < length / 3; ++count) {
+                read64();
+                close(readFence());
+            }
+            break;
+        default:
+            GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
+            break;
+    }
+}
+}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
index 9afc72f..02e5151 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
@@ -15,12 +15,18 @@
  */
 #pragma once
 
-#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
+#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
 #include <android-base/thread_annotations.h>
 #include <mutex>
 #include <unordered_set>
 
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 namespace aidl::android::hardware::graphics::composer3::vts {
 
 // IComposerCallback to be installed with IComposerClient::registerCallback.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
new file mode 100644
index 0000000..852a56e
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2021, 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
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <android/hardware/graphics/composer3/command-buffer.h>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+class TestCommandReader : public CommandReaderBase {
+  public:
+    virtual ~TestCommandReader() = default;
+
+    std::vector<std::pair<uint32_t, uint32_t>> mErrors;
+    std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
+
+    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
+    // unexpected errors or commands.
+    void parse();
+    virtual void parseSingleCommand(int32_t commandRaw, uint16_t length);
+};
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/health/aidl/README.md b/health/aidl/README.md
new file mode 100644
index 0000000..53a4f91
--- /dev/null
+++ b/health/aidl/README.md
@@ -0,0 +1,293 @@
+# Health AIDL HAL
+
+## Determine whether the example service implementation is sufficient {#determine}
+
+You need a custom implementation if any of the following is true:
+
+* You are migrating from a custom
+  [health 2.1 HIDL HAL implementation](../2.1/README.md).
+* System properties `ro.charger.enable_suspend` and/or `ro.charger.no_ui`
+  are set to a `true` value. See [below](#charger-sysprops).
+* The device supports offline charging mode, and the `service`
+  declaration with `class charger` in `init.rc` is different from the one
+  provided by the example implementation. See [below](#charger-init-rc).
+
+If the example HAL service is sufficient, [install it](#use-example). Otherwise,
+[implement a custom HAL service](#use-custom).
+
+### System properties for charger {#charger-sysprops}
+
+The health AIDL HAL service also provides functionalities of `charger`. As a
+result, the system charger at `/system/bin/charger` is deprecated.
+
+However, the health AIDL HAL service is not allowed to read `ro.charger.*`
+system properties. These properties include:
+* `ro.charger.enable_suspend`. If set, you need a custom health AIDL HAL
+  service. See [below](#charger-enable-suspend).
+* `ro.charger.no_ui`. If set, you need a custom health AIDL HAL service.
+  See [below](#charger-no-ui).
+* `ro.charger.draw_split_screen`. The system property is deprecated.
+* `ro.charger.draw_split_offset`. The system property is deprecated.
+* `ro.charger.disable_init_blank`. The system property is deprecated.
+
+If you need to set any of the deprecated system properties, contact
+[OWNERS](OWNERS).
+
+### Default `service` declaration for charger in `init.rc` {#charger-init-rc}
+
+See
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
+
+Check the `service` declaration in your device-specific `init.rc` file that
+has `class charger`. Most likely, the declaration looks something like this
+(Below is an excerpt from Pixel 3):
+
+```text
+service vendor.charger /system/bin/charger
+    class charger
+    seclabel u:r:charger:s0
+    user system
+    group system wakelock input
+    capabilities SYS_BOOT
+    file /dev/kmsg w
+    file /sys/fs/pstore/console-ramoops-0 r
+    file /sys/fs/pstore/console-ramoops r
+    file /proc/last_kmsg r
+```
+
+Compare each line against the one provided by the example health AIDL HAL
+service in
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
+Specifically:
+
+* You may ignore the `service` line. The name of the service does not matter.
+* If your service belongs to additional classes beside `charger`, you need a
+  custom health AIDL service.
+* You may ignore the `seclabel` line. When the health AIDL service runs in
+  charger mode, its original SELinux domain is kept.
+* If your service has a different `user` (not `system`), you need a custom
+  health AIDL service.
+* If your service belongs to additional `group`s beside
+  `system wakelock input`, you need a custom health AIDL service.
+* If your service requires additional capabilities beside `SYS_BOOT`,
+  you need a custom health AIDL service.
+* If your service requires additional `file`s to be opened prior to execution,
+  you need a custom health AIDL service.
+
+## Using the example health AIDL HAL service {#use-example}
+
+If you [determined](#determine) that the example health AIDL HAL service works
+for your device, install it with
+
+```mk
+PRODUCT_PACKAGES += android.hardware.health-service.example
+```
+
+Then, delete any existing `service` with `class charger` in your device-specific
+`init.rc` files, because
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
+already contains an entry for charger.
+
+If your device supports charger mode and it has custom charger resources,
+[move charger resources to `/vendor`](#charger-res)
+
+## Implementing a custom health AIDL HAL service {#use-custom}
+
+### Override the `Health` class {#health-impl}
+
+See [`Health.h`](default/include/health-impl/Health.h) for its class
+declaration. Inherit the class to customize for your device.
+
+```c++
+namespace aidl::android::hardware::health {
+class HealthImpl : public Health {
+    // ...
+};
+} // namespace aidl::android::hardware::health
+int main(int, char**) {
+    // ...
+    auto binder = ndk::SharedRefBase::make<aidl::android::hardware::health::HealthImpl>(
+            "default", std::move(config));
+    // ...
+}
+```
+
+* The logic to modify `healthd_config`, traditionally in `healthd_board_init()`
+  should be called before passing the `healthd_config` struct to your
+  `HealthImpl` class in [`main()`](#main).
+
+* The following functions are similar to the ones in the health 2.1 HIDL HAL:
+
+| AIDL implementation                 | HIDL implementation         |
+|-------------------------------------|-----------------------------|
+| `Health::getChargeCounterUah`       | `Health::getChargeCounter`  |
+| `Health::getCurrentNowMicroamps`    | `Health::getCurrentNow`     |
+| `Health::getCurrentAverageMicroamps`| `Health::getCurrentAverage` |
+| `Health::getCapacity`               | `Health::getCapacity`       |
+| `Health::getChargeStatus`           | `Health::getChargeStatus`   |
+| `Health::getEnergyCounterNwh`       | `Health::getEnergyCounter`  |
+| `Health::getDiskStats`              | `Health::getDiskStats`      |
+| `Health::getStorageInfo`            | `Health::getStorageInfo`    |
+| `Health::BinderEvent`               | `BinderHealth::BinderEvent` |
+| `Health::dump`                      | `Health::debug`             |
+| `Health::ShouldKeepScreenOn`        | `Health::shouldKeepScreenOn`|
+| `Health::UpdateHealthInfo`          | `Health::UpdateHealthInfo`  |
+
+### Implement `main()` {#main}
+
+See the [`main.cpp`](default/main.cpp) for the example health AIDL service for
+an example.
+
+If you need to modify `healthd_config`, do it before passing it to the
+constructor of `HealthImpl` (or `Health` if you did not implement a subclass
+of it).
+
+```c++
+int main(int argc, char** argv) {
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    healthd_board_init(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+    // ...
+}
+```
+
+If your device does not support off-line charging mode, or does not have a UI
+for charger (`ro.charger.no_ui=true`), skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+### SELinux rules
+
+Add device specific permissions to the domain where the health HAL
+process is executed, especially if a device-specific `libhealthd` is used
+and/or device-specific storage related APIs are implemented.
+
+If you did not define a separate domain, the domain is likely
+`hal_health_default`. The device-specific rules for it is likely at
+`device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te`.
+
+### Implementing charger {#charger}
+
+#### Move charger resources to `/vendor`
+
+Ensure that charger resources are installed to `/vendor`, not `/product`.
+
+`animation.txt` must be moved to the following location:
+
+```text
+/vendor/etc/res/values/charger/animation.txt
+```
+
+Charger resources in `/system` is not read by the health HAL service in
+`/vendor`. Specifically, resources should be installed to the following
+location:
+
+```
+/vendor/etc/res/images/charger/*.png
+```
+
+If resources are not found in these locations, the health HAL service falls
+back to the following locations:
+
+```
+/vendor/etc/res/images/charger/default/*.png
+```
+
+You can use the default resources by installing the default module:
+
+```makefile
+PRODUCT_PACKAGES += charger_res_images_vendor
+```
+
+#### Modify `init.rc` for charger
+
+It is recommended that you move the existing `service` entry with
+`class charger` to the `init.rc` file in your custom health service.
+
+Modify the entry to invoke the health service binary with `--charger` argument.
+See
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
+for an example:
+
+```text
+service vendor.charger-tuna /vendor/bin/hw/android.hardware.health-service-tuna --charger
+    # ...
+```
+
+#### No charger mode {#no-charger}
+
+If your device does not support off-line charging mode, skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+```c++
+int main(int, char**) {
+    // ...
+    // Skip checking if arguments contain "--charger"
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+    return hal_health_loop->StartLoop();
+}
+```
+
+You may optionally delete the `service` entry with `class charger` in the
+`init.rc` file.
+
+#### No charger UI {#charger-no-ui}
+
+If your device does not have a UI for charger (`ro.charger.no_ui=true`), skip
+the invocation of `ChargerModeMain()` in `main()`.
+
+You may want to keep the `KernelLogger` so that charger still logs battery
+information to the kernel logs.
+
+```c++
+int main(int argc, char** argv) {
+    // ...
+    if (argc >= 2 && argv[1] == "--charger"sv) {
+        android::base::InitLogging(argv, &android::base::KernelLogger);
+        // fallthrough to HalHealthLoop::StartLoop()
+    }
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+    return hal_health_loop->StartLoop();
+}
+```
+
+#### Enable suspend {#charger-enable-suspend}
+
+If your device has `ro.charger.enable_suspend=true`, implement a new class,
+`ChargerCallbackImpl`, that inherits from
+[`ChargerCallback`](default/include/health-impl/ChargerUtils.h). Then
+override the `ChargerEnableSuspend` function to return `true`. Then pass an
+instance of `ChargerCallbackImpl` to `ChargerModeMain()` instead.
+
+```c++
+namespace aidl::android::hardware::health {
+class ChargerCallbackImpl : public ChargerCallback {
+    bool ChargerEnableSuspend() override { return true; }
+};
+} // namespace aidl::android::hardware::health
+int main(int argc, char** argv) {
+    // ...
+    if (argc >= 2 && argv[1] == "--charger"sv) {
+        android::base::InitLogging(argv, &android::base::KernelLogger);
+#if !CHARGER_FORCE_NO_UI
+        return ChargerModeMain(binder,
+                std::make_shared<aidl::android::hardware::health::ChargerCallbackImpl>(binder));
+#endif
+    }
+    // ...
+}
+```
+
+#### SELinux rules for charger
+
+If your health AIDL service runs in a domain other than `hal_health_default`,
+add `charger_type` to it so the health HAL service can have charger-specific
+permissions. Example (assuming that your health AIDL service runs in domain
+`hal_health_tuna`:
+
+```text
+type hal_health_tuna, charger_type, domain;
+hal_server_domain(hal_health_default, hal_health)
+```
+
+[comment: TODO(b/170338625): explain recovery]: #
diff --git a/health/aidl/android/hardware/health/Translate.java b/health/aidl/android/hardware/health/Translate.java
index c8ace1c..4f840b8 100644
--- a/health/aidl/android/hardware/health/Translate.java
+++ b/health/aidl/android/hardware/health/Translate.java
@@ -44,25 +44,37 @@
         return out;
     }
 
+    private static void h2aTranslateInternal(
+            android.hardware.health.HealthInfo out, android.hardware.health.V1_0.HealthInfo in) {
+        out.chargerAcOnline = in.chargerAcOnline;
+        out.chargerUsbOnline = in.chargerUsbOnline;
+        out.chargerWirelessOnline = in.chargerWirelessOnline;
+        out.maxChargingCurrentMicroamps = in.maxChargingCurrent;
+        out.maxChargingVoltageMicrovolts = in.maxChargingVoltage;
+        out.batteryStatus = in.batteryStatus;
+        out.batteryHealth = in.batteryHealth;
+        out.batteryPresent = in.batteryPresent;
+        out.batteryLevel = in.batteryLevel;
+        out.batteryVoltageMillivolts = in.batteryVoltage;
+        out.batteryTemperatureTenthsCelsius = in.batteryTemperature;
+        out.batteryCurrentMicroamps = in.batteryCurrent;
+        out.batteryCycleCount = in.batteryCycleCount;
+        out.batteryFullChargeUah = in.batteryFullCharge;
+        out.batteryChargeCounterUah = in.batteryChargeCounter;
+        out.batteryTechnology = in.batteryTechnology;
+    }
+
+    public static android.hardware.health.HealthInfo h2aTranslate(
+            android.hardware.health.V1_0.HealthInfo in) {
+        android.hardware.health.HealthInfo out = new android.hardware.health.HealthInfo();
+        h2aTranslateInternal(out, in);
+        return out;
+    }
+
     static public android.hardware.health.HealthInfo h2aTranslate(
             android.hardware.health.V2_1.HealthInfo in) {
         android.hardware.health.HealthInfo out = new android.hardware.health.HealthInfo();
-        out.chargerAcOnline = in.legacy.legacy.chargerAcOnline;
-        out.chargerUsbOnline = in.legacy.legacy.chargerUsbOnline;
-        out.chargerWirelessOnline = in.legacy.legacy.chargerWirelessOnline;
-        out.maxChargingCurrentMicroamps = in.legacy.legacy.maxChargingCurrent;
-        out.maxChargingVoltageMicrovolts = in.legacy.legacy.maxChargingVoltage;
-        out.batteryStatus = in.legacy.legacy.batteryStatus;
-        out.batteryHealth = in.legacy.legacy.batteryHealth;
-        out.batteryPresent = in.legacy.legacy.batteryPresent;
-        out.batteryLevel = in.legacy.legacy.batteryLevel;
-        out.batteryVoltageMillivolts = in.legacy.legacy.batteryVoltage;
-        out.batteryTemperatureTenthsCelsius = in.legacy.legacy.batteryTemperature;
-        out.batteryCurrentMicroamps = in.legacy.legacy.batteryCurrent;
-        out.batteryCycleCount = in.legacy.legacy.batteryCycleCount;
-        out.batteryFullChargeUah = in.legacy.legacy.batteryFullCharge;
-        out.batteryChargeCounterUah = in.legacy.legacy.batteryChargeCounter;
-        out.batteryTechnology = in.legacy.legacy.batteryTechnology;
+        h2aTranslateInternal(out, in.legacy.legacy);
         out.batteryCurrentAverageMicroamps = in.legacy.batteryCurrentAverage;
         out.diskStats = new android.hardware.health.DiskStats[in.legacy.diskStats.size()];
         for (int i = 0; i < in.legacy.diskStats.size(); i++) {
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 7e635d4..a13c677 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -45,6 +45,52 @@
     ],
 }
 
+// Dependency to libhealthd_charger_ui. No UI in recovery.
+cc_defaults {
+    name: "libhealth_aidl_charger_defaults",
+    shared_libs: [
+        // common
+        "android.hardware.health-V1-ndk",
+        "libbase",
+        "libcutils",
+        "liblog",
+        "libutils",
+
+        // charger UI only
+        "libpng",
+    ],
+
+    static_libs: [
+        // common
+        "libbatterymonitor",
+        "libhealthloop",
+
+        // charger UI only
+        "libhealthd_draw",
+        "libhealthd_charger_ui",
+        "libminui",
+        "libsuspend",
+    ],
+
+    target: {
+        recovery: {
+            // No UI and libsuspend for recovery charger.
+            cflags: [
+                "-DCHARGER_FORCE_NO_UI=1",
+            ],
+            exclude_shared_libs: [
+                "libpng",
+            ],
+            exclude_static_libs: [
+                "libhealthd_draw",
+                "libhealthd_charger_ui",
+                "libminui",
+                "libsuspend",
+            ],
+        },
+    },
+}
+
 // AIDL version of libhealth2impl.
 // A helper library for health HAL implementation.
 // HAL implementations can link to this library and extend the Health class.
@@ -52,21 +98,26 @@
     name: "libhealth_aidl_impl",
     defaults: [
         "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
     ],
     export_include_dirs: ["include"],
     export_static_lib_headers: [
         "libbatterymonitor",
     ],
     srcs: [
+        "ChargerUtils.cpp",
         "health-convert.cpp",
         "HalHealthLoop.cpp",
         "Health.cpp",
         "LinkedCallback.cpp",
     ],
-    visibility: [
-        ":__subpackages__",
-        "//hardware/interfaces/tests/extension/health:__subpackages__",
-    ],
+    target: {
+        recovery: {
+            exclude_srcs: [
+                "ChargerUtils.cpp",
+            ],
+        },
+    },
 }
 
 // AIDL version of android.hardware.health@2.1-service.
@@ -78,9 +129,13 @@
     vintf_fragments: ["android.hardware.health-service.example.xml"],
     defaults: [
         "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
     ],
     static_libs: [
         "libhealth_aidl_impl",
     ],
     srcs: ["main.cpp"],
+    overrides: [
+        "charger",
+    ],
 }
diff --git a/health/aidl/default/ChargerUtils.cpp b/health/aidl/default/ChargerUtils.cpp
new file mode 100644
index 0000000..f8e208b
--- /dev/null
+++ b/health/aidl/default/ChargerUtils.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <health-impl/ChargerUtils.h>
+
+namespace aidl::android::hardware::health::charger {
+
+std::optional<bool> ChargerCallback::ChargerShouldKeepScreenOn() {
+    return service_->ShouldKeepScreenOn();
+}
+
+bool ChargerCallback::ChargerIsOnline() {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        // Assume no charger
+        return false;
+    }
+    return hal_health_loop_sp->charger_online();
+}
+
+void ChargerCallback::ChargerInitConfig(healthd_config* config) {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        return;
+    }
+    return service_->OnInit(hal_health_loop_sp.get(), config);
+}
+
+int ChargerCallback::ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        return -1;
+    }
+    return hal_health_loop_sp->RegisterEvent(fd, func, wakeup);
+}
+
+void ChargerCallback::set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop) {
+    hal_health_loop_ = std::move(hal_health_loop);
+}
+
+// Implements HalHealthLoopCallback for AIDL charger
+// Adapter of (Charger, Health) ->  HalHealthLoopCallback
+class LoopCallback : public HalHealthLoopCallback {
+  public:
+    LoopCallback(const std::shared_ptr<Health>& service, ChargerCallback* charger_callback)
+        : service_(service), charger_(std::make_unique<::android::Charger>(charger_callback)) {}
+
+    void OnHeartbeat() override {
+        service_->OnHeartbeat();
+        charger_->OnHeartbeat();
+    }
+    // Return the minimum timeout. Negative values are treated as no values.
+    int OnPrepareToWait() override {
+        int timeout1 = service_->OnPrepareToWait();
+        int timeout2 = charger_->OnPrepareToWait();
+
+        if (timeout1 < 0) return timeout2;
+        if (timeout2 < 0) return timeout1;
+        return std::min(timeout1, timeout2);
+    }
+
+    void OnInit(HalHealthLoop*, struct healthd_config* config) override {
+        // Charger::OnInit calls ChargerInitConfig, which calls into the real Health::OnInit.
+        charger_->OnInit(config);
+    }
+
+    void OnHealthInfoChanged(const HealthInfo& health_info) override {
+        charger_->OnHealthInfoChanged(::android::ChargerHealthInfo{
+                .battery_level = health_info.batteryLevel,
+                .battery_status = health_info.batteryStatus,
+        });
+        service_->OnHealthInfoChanged(health_info);
+    }
+
+  private:
+    std::shared_ptr<Health> service_;
+    std::unique_ptr<::android::Charger> charger_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+                    const std::shared_ptr<ChargerCallback>& charger_callback) {
+    LOG(INFO) << "Starting charger mode.";
+    //   parent stack ==========================================
+    //   current stack                                         ||
+    //    ||                                                   ||
+    //    V                                                    V
+    // hal_health_loop => loop_callback => charger --(raw)--> charger_callback
+    //    ^----------------(weak)---------------------------------'
+    auto loop_callback = std::make_shared<LoopCallback>(binder, charger_callback.get());
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, std::move(loop_callback));
+    charger_callback->set_hal_health_loop(hal_health_loop);
+    return hal_health_loop->StartLoop();
+}
+
+}  // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 812e64a..e1d1982 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -60,6 +60,8 @@
     battery_monitor_.init(healthd_config_.get());
 }
 
+Health::~Health() {}
+
 //
 // Getters.
 //
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index b393c58..dee3d11 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -4,3 +4,13 @@
     group system
     capabilities WAKE_ALARM BLOCK_SUSPEND
     file /dev/kmsg w
+
+service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
+    class charger
+    user system
+    group system wakelock input
+    capabilities SYS_BOOT
+    file /dev/kmsg w
+    file /sys/fs/pstore/console-ramoops-0 r
+    file /sys/fs/pstore/console-ramoops r
+    file /proc/last_kmsg r
diff --git a/health/aidl/default/include/health-impl/ChargerUtils.h b/health/aidl/default/include/health-impl/ChargerUtils.h
new file mode 100644
index 0000000..8f94181
--- /dev/null
+++ b/health/aidl/default/include/health-impl/ChargerUtils.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <optional>
+#include <type_traits>
+
+#include <android/binder_auto_utils.h>
+#include <charger/healthd_mode_charger.h>
+#include <health-impl/Health.h>
+
+#pragma once
+
+namespace aidl::android::hardware::health::charger {
+
+// Implements ChargerHalHealthLoopInterface for AIDL charger
+// Adapter of (Health, HalHealthLoop) -> ChargerHalHealthLoopInterface
+class ChargerCallback : public ::android::ChargerConfigurationInterface {
+  public:
+    ChargerCallback(const std::shared_ptr<Health>& service) : service_(service) {}
+    std::optional<bool> ChargerShouldKeepScreenOn() override;
+    bool ChargerIsOnline() override;
+    void ChargerInitConfig(healthd_config* config) override;
+    int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) override;
+
+    // Override to return true to replace `ro.charger.enable_suspend=true`
+    bool ChargerEnableSuspend() override { return false; }
+
+    void set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop);
+
+  private:
+    std::shared_ptr<Health> service_;
+    std::weak_ptr<HalHealthLoop> hal_health_loop_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+                    const std::shared_ptr<ChargerCallback>& charger_callback);
+
+}  // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index e49f44c..6bd4946 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -43,6 +43,7 @@
     // A subclass may modify |config| before passing it to the parent constructor.
     // See implementation of Health for code samples.
     Health(std::string_view instance_name, std::unique_ptr<struct healthd_config>&& config);
+    virtual ~Health();
 
     ndk::ScopedAStatus registerCallback(
             const std::shared_ptr<IHealthInfoCallback>& callback) override;
diff --git a/health/aidl/default/main.cpp b/health/aidl/default/main.cpp
index 014ae34..76c6ba0 100644
--- a/health/aidl/default/main.cpp
+++ b/health/aidl/default/main.cpp
@@ -19,17 +19,46 @@
 #include <health-impl/Health.h>
 #include <health/utils.h>
 
+#ifndef CHARGER_FORCE_NO_UI
+#define CHARGER_FORCE_NO_UI 0
+#endif
+
+#if !CHARGER_FORCE_NO_UI
+#include <health-impl/ChargerUtils.h>
+#endif
+
 using aidl::android::hardware::health::HalHealthLoop;
 using aidl::android::hardware::health::Health;
 
-static constexpr const char* gInstanceName = "default";
+#if !CHARGER_FORCE_NO_UI
+using aidl::android::hardware::health::charger::ChargerCallback;
+using aidl::android::hardware::health::charger::ChargerModeMain;
+#endif
 
-int main() {
-    // TODO(b/203246116): handle charger
+static constexpr const char* gInstanceName = "default";
+static constexpr std::string_view gChargerArg{"--charger"};
+
+int main(int argc, char** argv) {
     // make a default health service
     auto config = std::make_unique<healthd_config>();
     ::android::hardware::health::InitHealthdConfig(config.get());
     auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
+
+    if (argc >= 2 && argv[1] == gChargerArg) {
+        android::base::InitLogging(argv, &android::base::KernelLogger);
+
+#if !CHARGER_FORCE_NO_UI
+        // If charger shouldn't have UI for your device, simply drop the line below
+        // for your service implementation. This corresponds to
+        // ro.charger.no_ui=true
+        return ChargerModeMain(binder, std::make_shared<ChargerCallback>(binder));
+#endif
+
+        LOG(INFO) << "Starting charger mode without UI.";
+    } else {
+        LOG(INFO) << "Starting health HAL.";
+    }
+
     auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
     return hal_health_loop->StartLoop();
 }
diff --git a/health/utils/libhealthtest/Android.bp b/health/utils/libhealthtest/Android.bp
index dbe02d6..0993cb6 100644
--- a/health/utils/libhealthtest/Android.bp
+++ b/health/utils/libhealthtest/Android.bp
@@ -13,6 +13,15 @@
 // limitations under the License.
 
 // Utils library for VTS tests.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
 cc_library_headers {
     name: "libhealthtest_headers",
     static_libs: [
diff --git a/neuralnetworks/1.0/utils/OWNERS b/neuralnetworks/1.0/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.0/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.0/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.0/vts/functional/OWNERS b/neuralnetworks/1.0/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.1/utils/OWNERS b/neuralnetworks/1.1/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.1/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.1/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.1/vts/functional/OWNERS b/neuralnetworks/1.1/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.2/utils/OWNERS b/neuralnetworks/1.2/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.2/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.2/vts/OWNERS b/neuralnetworks/1.2/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.2/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.2/vts/functional/OWNERS b/neuralnetworks/1.2/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.3/utils/OWNERS b/neuralnetworks/1.3/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.3/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.3/vts/OWNERS b/neuralnetworks/1.3/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.3/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.3/vts/functional/OWNERS b/neuralnetworks/1.3/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.3/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/aidl/vts/OWNERS b/neuralnetworks/OWNERS
similarity index 78%
rename from neuralnetworks/aidl/vts/OWNERS
rename to neuralnetworks/OWNERS
index f1a757a..def3ea9 100644
--- a/neuralnetworks/aidl/vts/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,9 +1,10 @@
+# Bug component: 195575
 # Neuralnetworks team
 butlermichael@google.com
 dgross@google.com
+galarragas@google.com
+ianhua@google.com
 jeanluc@google.com
 miaowang@google.com
-mikie@google.com
 pszczepaniak@google.com
 xusongw@google.com
-ianhua@google.com
diff --git a/neuralnetworks/README b/neuralnetworks/README
index d8c8f5d..b0c605d 100644
--- a/neuralnetworks/README
+++ b/neuralnetworks/README
@@ -1,2 +1,2 @@
 NeuralNetworks sample driver implementation is located at
-frameworks/ml/nn/driver/sample.
+packages/modules/NeuralNetworks/driver/sample*.
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index a31157a..cbb6ce5 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -35,5 +35,8 @@
             min_sdk_version: "30",
         },
     },
-    versions: ["1"],
+    versions: [
+        "1",
+        "2",
+    ],
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash
new file mode 100644
index 0000000..35f32ea
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash
@@ -0,0 +1 @@
+04c95c94c96062e5faf35c00b4ae0e50a3f11d0d
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
index 6eadbb7..05cec76 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,8 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable BufferDesc {
+  int[] dimensions;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
similarity index 89%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
index 9bfb725..10a6b75 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapApduType {
-  APDU = 0,
-  APDU7816 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable BufferRole {
+  int modelIndex;
+  int ioIndex;
+  float probability;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
index 0c6c513..30877c0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,12 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Capabilities {
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
+  android.hardware.neuralnetworks.OperandPerformance[] operandPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo ifPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo whilePerformance;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
index a03f519..db49a38 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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.radio.network;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+parcelable DataLocation {
+  int poolIndex;
+  long offset;
+  long length;
+  long padding;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
index a03f519..7cdd6db 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio.network;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+parcelable DeviceBuffer {
+  android.hardware.neuralnetworks.IBuffer buffer;
+  int token;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
similarity index 90%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
index 6eadbb7..82fe8ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum DeviceType {
+  OTHER = 1,
+  CPU = 2,
+  GPU = 3,
+  ACCELERATOR = 4,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
similarity index 81%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
index 0c6c513..57d5d6e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,16 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum ErrorStatus {
+  NONE = 0,
+  DEVICE_UNAVAILABLE = 1,
+  GENERAL_FAILURE = 2,
+  OUTPUT_INSUFFICIENT_SIZE = 3,
+  INVALID_ARGUMENT = 4,
+  MISSED_DEADLINE_TRANSIENT = 5,
+  MISSED_DEADLINE_PERSISTENT = 6,
+  RESOURCE_EXHAUSTED_TRANSIENT = 7,
+  RESOURCE_EXHAUSTED_PERSISTENT = 8,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
index 6eadbb7..4352d8f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum ExecutionPreference {
+  LOW_POWER = 0,
+  FAST_SINGLE_ANSWER = 1,
+  SUSTAINED_SPEED = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
index d7eecbb..44e9922 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
@@ -31,8 +31,10 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable ExecutionResult {
+  boolean outputSufficientSize;
+  android.hardware.neuralnetworks.OutputShape[] outputShapes;
+  android.hardware.neuralnetworks.Timing timing;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
index d7eecbb..c47028d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Extension {
+  String name;
+  android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
index 6eadbb7..6c287fd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionNameAndPrefix {
+  String name;
+  char prefix;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
index 6eadbb7..a3680aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionOperandTypeInformation {
+  char type;
+  boolean isTensor;
+  int byteSize;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
index d7eecbb..7952b34 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable FencedExecutionResult {
+  android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+  @nullable ParcelFileDescriptor syncFence;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
index 6eadbb7..7e61bbb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum FusedActivationFunc {
+  NONE = 0,
+  RELU = 1,
+  RELU1 = 2,
+  RELU6 = 3,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
index d7eecbb..f10e7e2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBuffer {
+  void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions);
+  void copyTo(in android.hardware.neuralnetworks.Memory dst);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
similarity index 82%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
index d7eecbb..eb3d0b0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBurst {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  void releaseMemoryResource(in long memoryIdentifierToken);
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl
new file mode 100644
index 0000000..c9c67f2
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@VintfStability
+interface IDevice {
+  android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles);
+  android.hardware.neuralnetworks.Capabilities getCapabilities();
+  android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded();
+  android.hardware.neuralnetworks.Extension[] getSupportedExtensions();
+  boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model);
+  android.hardware.neuralnetworks.DeviceType getType();
+  String getVersionString();
+  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  const int BYTE_SIZE_OF_CACHE_TOKEN = 32;
+  const int MAX_NUMBER_OF_CACHE_FILES = 32;
+  const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15;
+  const int EXTENSION_TYPE_LOW_BITS_TYPE = 16;
+  const int OPERAND_TYPE_BASE_MAX = 65535;
+  const int OPERATION_TYPE_BASE_MAX = 65535;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
index d7eecbb..0bfb80a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,8 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IFencedExecutionCallback {
+  android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
similarity index 67%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
index 0c6c513..fccb5dc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,12 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IPreparedModel {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
+  android.hardware.neuralnetworks.IBurst configureExecutionBurst();
+  const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
+  const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
index d7eecbb..e0c763b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,8 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IPreparedModelCallback {
+  void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
index 6eadbb7..dbedf12 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,8 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable IPreparedModelParcel {
+  android.hardware.neuralnetworks.IPreparedModel preparedModel;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
index d7eecbb..37fa102 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,10 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union Memory {
+  android.hardware.common.Ashmem ashmem;
+  android.hardware.common.MappableFile mappableFile;
+  android.hardware.graphics.common.HardwareBuffer hardwareBuffer;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
similarity index 79%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
index d7eecbb..30d8dda 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,13 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Model {
+  android.hardware.neuralnetworks.Subgraph main;
+  android.hardware.neuralnetworks.Subgraph[] referenced;
+  byte[] operandValues;
+  android.hardware.neuralnetworks.Memory[] pools;
+  boolean relaxComputationFloat32toFloat16;
+  android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
index 6eadbb7..9314760 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable NumberOfCacheFiles {
+  int numModelCache;
+  int numDataCache;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
index d7eecbb..1d9bdd8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,14 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Operand {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  int[] dimensions;
+  float scale;
+  int zeroPoint;
+  android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE;
+  android.hardware.neuralnetworks.DataLocation location;
+  @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
index d7eecbb..14792cf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union OperandExtraParams {
+  android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant;
+  byte[] extension;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
index 6eadbb7..40adfb1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,14 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum OperandLifeTime {
+  TEMPORARY_VARIABLE = 0,
+  SUBGRAPH_INPUT = 1,
+  SUBGRAPH_OUTPUT = 2,
+  CONSTANT_COPY = 3,
+  CONSTANT_POOL = 4,
+  NO_VALUE = 5,
+  SUBGRAPH = 6,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
index d7eecbb..ebb361b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable OperandPerformance {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  android.hardware.neuralnetworks.PerformanceInfo info;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
similarity index 77%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
index 0c6c513..9f2c759 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,23 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum OperandType {
+  FLOAT32 = 0,
+  INT32 = 1,
+  UINT32 = 2,
+  TENSOR_FLOAT32 = 3,
+  TENSOR_INT32 = 4,
+  TENSOR_QUANT8_ASYMM = 5,
+  BOOL = 6,
+  TENSOR_QUANT16_SYMM = 7,
+  TENSOR_FLOAT16 = 8,
+  TENSOR_BOOL8 = 9,
+  FLOAT16 = 10,
+  TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
+  TENSOR_QUANT16_ASYMM = 12,
+  TENSOR_QUANT8_SYMM = 13,
+  TENSOR_QUANT8_ASYMM_SIGNED = 14,
+  SUBGRAPH = 15,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
index 6eadbb7..a4a3fbe 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Operation {
+  android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD;
+  int[] inputs;
+  int[] outputs;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl
new file mode 100644
index 0000000..2eff11b
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperationType {
+  ADD = 0,
+  AVERAGE_POOL_2D = 1,
+  CONCATENATION = 2,
+  CONV_2D = 3,
+  DEPTHWISE_CONV_2D = 4,
+  DEPTH_TO_SPACE = 5,
+  DEQUANTIZE = 6,
+  EMBEDDING_LOOKUP = 7,
+  FLOOR = 8,
+  FULLY_CONNECTED = 9,
+  HASHTABLE_LOOKUP = 10,
+  L2_NORMALIZATION = 11,
+  L2_POOL_2D = 12,
+  LOCAL_RESPONSE_NORMALIZATION = 13,
+  LOGISTIC = 14,
+  LSH_PROJECTION = 15,
+  LSTM = 16,
+  MAX_POOL_2D = 17,
+  MUL = 18,
+  RELU = 19,
+  RELU1 = 20,
+  RELU6 = 21,
+  RESHAPE = 22,
+  RESIZE_BILINEAR = 23,
+  RNN = 24,
+  SOFTMAX = 25,
+  SPACE_TO_DEPTH = 26,
+  SVDF = 27,
+  TANH = 28,
+  BATCH_TO_SPACE_ND = 29,
+  DIV = 30,
+  MEAN = 31,
+  PAD = 32,
+  SPACE_TO_BATCH_ND = 33,
+  SQUEEZE = 34,
+  STRIDED_SLICE = 35,
+  SUB = 36,
+  TRANSPOSE = 37,
+  ABS = 38,
+  ARGMAX = 39,
+  ARGMIN = 40,
+  AXIS_ALIGNED_BBOX_TRANSFORM = 41,
+  BIDIRECTIONAL_SEQUENCE_LSTM = 42,
+  BIDIRECTIONAL_SEQUENCE_RNN = 43,
+  BOX_WITH_NMS_LIMIT = 44,
+  CAST = 45,
+  CHANNEL_SHUFFLE = 46,
+  DETECTION_POSTPROCESSING = 47,
+  EQUAL = 48,
+  EXP = 49,
+  EXPAND_DIMS = 50,
+  GATHER = 51,
+  GENERATE_PROPOSALS = 52,
+  GREATER = 53,
+  GREATER_EQUAL = 54,
+  GROUPED_CONV_2D = 55,
+  HEATMAP_MAX_KEYPOINT = 56,
+  INSTANCE_NORMALIZATION = 57,
+  LESS = 58,
+  LESS_EQUAL = 59,
+  LOG = 60,
+  LOGICAL_AND = 61,
+  LOGICAL_NOT = 62,
+  LOGICAL_OR = 63,
+  LOG_SOFTMAX = 64,
+  MAXIMUM = 65,
+  MINIMUM = 66,
+  NEG = 67,
+  NOT_EQUAL = 68,
+  PAD_V2 = 69,
+  POW = 70,
+  PRELU = 71,
+  QUANTIZE = 72,
+  QUANTIZED_16BIT_LSTM = 73,
+  RANDOM_MULTINOMIAL = 74,
+  REDUCE_ALL = 75,
+  REDUCE_ANY = 76,
+  REDUCE_MAX = 77,
+  REDUCE_MIN = 78,
+  REDUCE_PROD = 79,
+  REDUCE_SUM = 80,
+  ROI_ALIGN = 81,
+  ROI_POOLING = 82,
+  RSQRT = 83,
+  SELECT = 84,
+  SIN = 85,
+  SLICE = 86,
+  SPLIT = 87,
+  SQRT = 88,
+  TILE = 89,
+  TOPK_V2 = 90,
+  TRANSPOSE_CONV_2D = 91,
+  UNIDIRECTIONAL_SEQUENCE_LSTM = 92,
+  UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+  RESIZE_NEAREST_NEIGHBOR = 94,
+  QUANTIZED_LSTM = 95,
+  IF = 96,
+  WHILE = 97,
+  ELU = 98,
+  HARD_SWISH = 99,
+  FILL = 100,
+  RANK = 101,
+  BATCH_MATMUL = 102,
+  PACK = 103,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
index 6eadbb7..f733505 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable OutputShape {
+  int[] dimensions;
+  boolean isSufficient;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
index 6eadbb7..04910f5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable PerformanceInfo {
+  float execTime;
+  float powerUsage;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
similarity index 91%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
index 6eadbb7..8f35709 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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.radio;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum Priority {
+  LOW = 0,
+  MEDIUM = 1,
+  HIGH = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
index d7eecbb..39ec7a9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,10 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Request {
+  android.hardware.neuralnetworks.RequestArgument[] inputs;
+  android.hardware.neuralnetworks.RequestArgument[] outputs;
+  android.hardware.neuralnetworks.RequestMemoryPool[] pools;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
index d7eecbb..e3541c0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,10 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable RequestArgument {
+  boolean hasNoValue;
+  android.hardware.neuralnetworks.DataLocation location;
+  int[] dimensions;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
similarity index 89%
rename from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
index a03f519..312f581 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio.network;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+union RequestMemoryPool {
+  android.hardware.neuralnetworks.Memory pool;
+  int token;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
index d7eecbb..b7d4451 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,11 @@
 // 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.radio.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Subgraph {
+  android.hardware.neuralnetworks.Operand[] operands;
+  android.hardware.neuralnetworks.Operation[] operations;
+  int[] inputIndexes;
+  int[] outputIndexes;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
index 6eadbb7..02d68f9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable SymmPerChannelQuantParams {
+  float[] scales;
+  int channelDim;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
index 6eadbb7..bcc83cf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Timing {
+  long timeOnDeviceNs;
+  long timeInDriverNs;
 }
diff --git a/neuralnetworks/aidl/utils/OWNERS b/neuralnetworks/aidl/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/aidl/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h b/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
deleted file mode 100644
index 4421876..0000000
--- a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "nnapi/hal/aidl/BufferTracker.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h b/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
deleted file mode 100644
index 3777969..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "nnapi/hal/aidl/HalInterfaces.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalUtils.h b/neuralnetworks/aidl/utils/include/AidlHalUtils.h
deleted file mode 100644
index 98bfbad..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalUtils.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "nnapi/hal/aidl/HalUtils.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlValidateHal.h b/neuralnetworks/aidl/utils/include/AidlValidateHal.h
deleted file mode 100644
index 5aaa74d..0000000
--- a/neuralnetworks/aidl/utils/include/AidlValidateHal.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "nnapi/hal/aidl/ValidateHal.h"
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index f2ab479..1fb694b 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -19,6 +19,7 @@
 
 #include "nnapi/hal/aidl/Conversions.h"
 
+#include <aidl/android/hardware/neuralnetworks/IDevice.h>
 #include <android-base/logging.h>
 #include <nnapi/Result.h>
 #include <nnapi/TypeUtils.h>
@@ -28,7 +29,19 @@
 namespace aidl::android::hardware::neuralnetworks::utils {
 
 constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::FEATURE_LEVEL_6;
+
+constexpr std::optional<nn::Version> aidlVersionToCanonicalVersion(int aidlVersion) {
+    switch (aidlVersion) {
+        case 1:
+            return nn::Version::ANDROID_S;
+        case 2:
+            return nn::Version::FEATURE_LEVEL_6;
+        default:
+            return std::nullopt;
+    }
+}
+
+constexpr auto kVersion = aidlVersionToCanonicalVersion(IDevice::version).value();
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
diff --git a/neuralnetworks/aidl/utils/src/Buffer.cpp b/neuralnetworks/aidl/utils/src/Buffer.cpp
index c729a68..9af3c9e 100644
--- a/neuralnetworks/aidl/utils/src/Buffer.cpp
+++ b/neuralnetworks/aidl/utils/src/Buffer.cpp
@@ -22,7 +22,6 @@
 
 #include "Conversions.h"
 #include "Utils.h"
-#include "nnapi/hal/aidl/Conversions.h"
 
 #include <memory>
 #include <utility>
diff --git a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
rename to neuralnetworks/aidl/utils/src/BufferTracker.cpp
index 15d0810..94dc891 100644
--- a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
+++ b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
-#include "AidlBufferTracker.h"
+#include "BufferTracker.h"
+
+#include "HalInterfaces.h"
 
 #include <android-base/macros.h>
+#include <nnapi/TypeUtils.h>
 
 #include <memory>
 #include <mutex>
@@ -25,9 +28,6 @@
 #include <utility>
 #include <vector>
 
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android::nn {
 
 std::shared_ptr<AidlManagedBuffer> AidlManagedBuffer::create(
diff --git a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp b/neuralnetworks/aidl/utils/src/HalUtils.cpp
similarity index 96%
rename from neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
rename to neuralnetworks/aidl/utils/src/HalUtils.cpp
index 6fc46ab..64b6259 100644
--- a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
+++ b/neuralnetworks/aidl/utils/src/HalUtils.cpp
@@ -17,9 +17,12 @@
 // utilities. LegacyUtils.h is the subset of these utilities that do not touch
 // HAL.
 
-#include "AidlHalUtils.h"
+#include "HalUtils.h"
+
+#include "HalInterfaces.h"
 
 #include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
 #include <nnapi/hal/aidl/Conversions.h>
 
 #include <algorithm>
@@ -27,9 +30,6 @@
 #include <type_traits>
 #include <vector>
 
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android::nn {
 
 std::vector<aidl_hal::OperandPerformance> nonExtensionOperandPerformance(
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index 01772ee..e48593c 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -46,13 +46,11 @@
     aidlVersion = std::min(aidlVersion, IDevice::version);
 
     // Map stable AIDL versions to canonical versions.
-    switch (aidlVersion) {
-        case 1:
-            return nn::Version::ANDROID_S;
-        case 2:
-            return nn::Version::FEATURE_LEVEL_6;
+    auto version = aidlVersionToCanonicalVersion(aidlVersion);
+    if (!version.has_value()) {
+        return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
     }
-    return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
+    return version.value();
 }
 
 }  // namespace
diff --git a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
rename to neuralnetworks/aidl/utils/src/ValidateHal.cpp
index a1c496a..a56de21 100644
--- a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
+++ b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
@@ -16,9 +16,12 @@
 
 #define LOG_TAG "ValidateHal"
 
-#include "AidlValidateHal.h"
+#include "ValidateHal.h"
+
+#include "HalUtils.h"
 
 #include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
 #include <nnapi/hal/aidl/Conversions.h>
 
 #include <algorithm>
@@ -27,9 +30,6 @@
 #include <utility>
 #include <vector>
 
-#include "AidlHalUtils.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android {
 namespace nn {
 
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index 1819699..cd5475c 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -28,9 +28,9 @@
 #include <Utils.h>
 #include <nnapi/SharedMemory.h>
 #include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/HalInterfaces.h>
 #include <nnapi/hal/aidl/Utils.h>
 
-#include "AidlHalInterfaces.h"
 #include "Callbacks.h"
 #include "GeneratedTestHarness.h"
 #include "MemoryUtils.h"
diff --git a/neuralnetworks/utils/OWNERS b/neuralnetworks/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e10d329..9acb9e0 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -24,8 +24,8 @@
 cc_binary {
     name: "android.hardware.power-service.example",
     relative_install_path: "hw",
-    init_rc: ["power-default.rc"],
-    vintf_fragments: ["power-default.xml"],
+    init_rc: [":android.hardware.power.rc"],
+    vintf_fragments: [":android.hardware.power.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
@@ -37,3 +37,13 @@
         "Power.cpp",
     ],
 }
+
+filegroup {
+    name: "android.hardware.power.xml",
+    srcs: ["power-default.xml"],
+}
+
+filegroup {
+    name: "android.hardware.power.rc",
+    srcs: ["power-default.rc"],
+}
diff --git a/power/aidl/default/apex/Android.bp b/power/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..eb04087
--- /dev/null
+++ b/power/aidl/default/apex/Android.bp
@@ -0,0 +1,72 @@
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+apex_key {
+    name: "com.android.hardware.power.key",
+    public_key: "com.android.hardware.power.avbpubkey",
+    private_key: "com.android.hardware.power.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.power.certificate",
+    certificate: "com.android.hardware.power",
+}
+
+genrule {
+    name: "com.android.hardware.power.rc-srcs",
+    srcs: [
+        ":android.hardware.power.rc",
+        ":android.hardware.power.stats.rc",
+    ],
+    out: ["com.android.hardware.power.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.power/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.power.rc",
+    src: ":com.android.hardware.power.rc-srcs",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.power",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.power.key",
+    certificate: ":com.android.hardware.power.certificate",
+    file_contexts: "file_contexts",
+    use_vndk_as_stable: true,
+    updatable: false,
+    // Install the apex in /vendor/apex
+    soc_specific: true,
+    // Bundle the Power and PowerStats HALs into this one APEX.
+    binaries: [
+        "android.hardware.power-service.example",
+        "android.hardware.power.stats-service.example",
+    ],
+    prebuilts: [
+        "com.android.hardware.power.rc",
+    ],
+    vintf_fragments: [
+        ":android.hardware.power.xml",
+        ":android.hardware.power.stats.xml",
+    ],
+    overrides: [
+        // Shared lib installed by default but unused by the AIDL implementation.
+        "power.default",
+    ],
+}
diff --git a/power/aidl/default/apex/apex_manifest.json b/power/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..faa937d
--- /dev/null
+++ b/power/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.power",
+  "version": 1
+}
diff --git a/power/aidl/default/apex/com.android.hardware.power.avbpubkey b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
new file mode 100644
index 0000000..3b6411d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.pem b/power/aidl/default/apex/com.android.hardware.power.pem
new file mode 100644
index 0000000..d18ae98
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAsUdFjtLq05tWKdQd4aj8V7tmV4KXw41pKGT5Q1CPzrdHF3yJ
+B/8VWdMpjZ+eQO1q8SijPgfvWExeWQVMfxKmwTmj26xWXhIOgo5G02Zva7zOptig
+KGnl/RdFlOiIGC36XeWDhzdIOhlGv+er9Sykf6Ot84OvktTBUTZNJrXQsyYTBRUX
+6B+wloPdBVxVf1HgzjeHUyCy5dTz0xZSWWELoW24tHIvV5FtJVKSY8ZDfuXWLLfT
+he7E93TepjT027U/J/iW4ITJzw4Qq87ick1D/jZDUbTrkqUMFEgPdgCouZ9zt5xG
+pcHAZ/Fcz9DZfEdX9Xy0R5/XbfrJdvDPguJlwK1pZnr/Pe13xxmE+TEohMmaQDqX
+jQNX3UlcfOYUAjnFMGucHDM10KjTMbP8ytCys88aNLiv7FOgVGrQ/djZN8rkMyVP
+ccoksUBMQmjYaQQZ2yZuJMiLD3P6aYkgU5tMEMoMTrBzfcx05GfElal+ZqOFKAzj
+eUxoZTR27wJb684FRbeE45D+y4jpFfrTEXry+aI7GrfDsVDnUqmyObCUttRtaT04
+6kuUmC44wFEg1EBfcWZc1szI192GBjMuZjFcYvJ4vMdCuennqvLNPBDY1PtqzCOf
+D8vpOE3T9rjS23xxFmmSmorwKKQOGChKqO/SaY0axkXgt+FbSsvTBQtZTSsCAwEA
+AQKCAgEArEu3t+MYJcdwS8EDtcF2V5IkGmMrOvziOkdA14Kh8efBKXt49xOc3atU
+VHfQ6AuXh4DWf0BZB7lZbS2wNkSbW2q47ZSmcFEeVxcOkQGawtxDAHfD2ONrirqm
+ft4s/0sYbU/WsIEzKnxMfdEdGHFmA0PCmczfxFYQ+OxMuZW1m5ginirtDEZYa0EH
+e+FMmyypz+K6HDnIhYWd4Aduy718/0zTWlUr2/DUYpTJAD2+dcPNj7Kt2xq/xj2I
+84K+hBa4phF+GgIU3a8u1ryA61RbA+QbM3siBWlxvvh2RlrHoXjuj4JMS2dup9c2
+PCggaCAyxb2IvaAFUbePPJE5LVz6RFT4HnLEydd5Yt+CEAm+iZKfCzyUgFRtb5y0
+HHTME1eVAt/rf/yIXUYA7q8nQ/PtSzIol5KLX4FUjX1MVKNmIWMa+836kxbuYDFB
+K1M1IKc1k0t9Q9F3TRCMhP/6qH/vJfubCGQhSRUMq7JyjivK9GjYST8R07Dpgu9Z
+4i9TRI8d+UVERsg8niCXONVkmNa3U49u2duUvqV3KmKgQ/Hgyy3keDjz6x56ie5w
+e0EusHAsot60W1BvHrdwlmGZjW3JmZEyazUPh9nBUAaQve1rIOpn80kGXx4EAE2o
+HcrcInJx/zVBk1Wk3UQDwmhUNpa64q9+nd9VMaR9SQNK3ah4NDECggEBAOeput2F
+CgRrvzka69i7FbgY4VmpNMIICPIB6gxvwpir/g4/GgYknuBB6ep1ksf/IZfsMp5A
+JTH1KdXqqQm8nV9v+ETYQAO+VnmWKSBKHsNJqONxsKkQ+xIJcusmKBTYLfL88XQg
+YWH3VMXgqPP8DnJYCeVRIKj1WqfEFFHiaLJJB8FgKhtZBwBnibkVG1K0XCkTdUfY
+mME2GRKW/C7DMvuFOpcFVj7Obwn68R2k3zsOhWA5NQGZF5mqhg5KYLVDg3IbMJQQ
+D+DymQxnc2s2ar0q24isy1Y/FOXrA057j1vAN951+pk6F/PCJM/mtAiRjhP0Aru1
+P6bbR11p+wnpU7MCggEBAMPm8Jmwu3F0xsyFC+1sWPAzPiwaMa7/30wANNKKqHVO
+7lUv1WYFbFMyAOzYPp3Y5HxdxNa43reULGk0R20kSu6W6FkApSvAws0rLKRlS5UI
+oZqhLGHUH2M7q07m2RgQY2TJkU2Zq6AH1kjcbSr127ISXKanKpqonwSHy38BTcGt
+Dl2fVioPzK/vwmiNo2njhh95TV4kqlbUfl7xtDt56tbg8oFBwOsK7UGajXYOxTGB
+o1DtO5E+oiOmlclXuo3m4qpSSMv+wM91aRFhHZVIx0vmO8y5lrfU2kM/5DDhJBxV
+FM4TaA+c5tFOTuCLejHc7nM99wVx7O4QZ0wBwETUxKkCggEAH0tBT+1J1iEL+tXV
+KDjVjUHnJyqBUvis5Kw3hqiOO/t33UrO5CeMQrUEuURaqKOhURl6GQCHRcFdfmUt
+ooAVLjA89GfV9et/WPtc4NzCXRUVOGxCNgRyNhSKrpM/9NjjFCDxKQO6w/YaQITB
+rfvNo8qaw5x68ff64BDPweP4yqSs5IVuCrWzCW3zH8pnH3v3uyDCxgrPT8JUDrvQ
+oyyBNZLgwEfbR66xN0Lr0VpVQXALulzf+TBKDNsJMuL/P104Y3Ci1k15J6T94bwT
+zlbSgm1IrKTS7vqkgw6FKtPsILPNmEKNsKc1VxtRx7fdeA7Zh3595Adu6sZSVJ8d
+Z1BamwKCAQAnbu0vgqu4gtEhigaEnDKq5yW0qvElUMwZ+FCpsM+IDYNcEmzaRG0x
+sfcNtdmk3GvhvN5KepwaR/FInAVkqtGKhUXv5Hla/Uo5El/CF8HHFh2xio/sgU5w
+IyqwjzdT6LiZKRnejPhHFkzEDdrLswGuLpQH185zo02fE9aakiCcw8EIh3JItTV2
+lMSFVz11qx7sZvZz5N2E7PEjG3Q0JK5o4o7uBdZXebOYaQvgn8iB1p6RQ6+h5QGu
+O3IbPVWICtnFfxq4NWeKWw/zN6FE04mKdaXD5/e2uVnV/55nWGp0aYvuj2l6+xJb
+P3ARMwI910MIX4jBx9TxdsvUOOYC9PFBAoIBAQDWswLnaNth4pgutngVWbMenSpv
+eK1RA1ldw2NoTZrGlqPB+LvjEMSH/7ioby8YtOyJRIWs3si8HpVF12qneu8qi7b7
+QlUtqyJOTnGalvhrlq5zPhdW+kk2DXvtTylUnz3vSxxi2I7cLhQRryLC/1kAwy67
+wEr0+u59bOvaqe8L1zgtYJpLQZeskUMzdSMIRVDdFShEFrMJU7adUvGpA7OZ6Ogf
+ux2jWr2vv/eKq6fU6kDPi/66MQjPbZPf2Uq6+XedkNkAeELpN4o3hw0/l/rfiK/r
+YUMJBwtjQw/hehtvC4GlgsH1tMZWzCZULo0tcW4qbzyi9PBrWFPteb33OjBc
+-----END RSA PRIVATE KEY-----
diff --git a/power/aidl/default/apex/com.android.hardware.power.pk8 b/power/aidl/default/apex/com.android.hardware.power.pk8
new file mode 100644
index 0000000..e45435d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pk8
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.x509.pem b/power/aidl/default/apex/com.android.hardware.power.x509.pem
new file mode 100644
index 0000000..9f0c5f0
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8ECFDFsXbm5CdS/UtQZgTiF8Umr8LrLMA0GCSqGSIb3DQEBCwUAMIGn
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEjMCEGA1UEAwwaY29t
+LmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwIBcNMjExMDIwMTcwNTA0WhgPNDc1OTA5
+MTYxNzA1MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
+MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
+CwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEj
+MCEGA1UEAwwaY29tLmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwggIiMA0GCSqGSIb3
+DQEBAQUAA4ICDwAwggIKAoICAQC/37fhOkOfgM2e+M7bMJ1baLFif8dKGwRa6mkJ
+9HWmuOgRcTKllzuEHtrJ0jzur3cDy6/0oZSfA/E1ck3DdRHMQadW26JSNSg6fCU9
+h1kDzkakZgyr3DsJnKGoSHCJ2V2kVbCnd6GuOaOU1ZZISw1I+BWJDc3t1mZPs80D
+ar7/hoIZnsWRoE/eWgJDcWWscRsquSi+q6hyqlCbRvwRznPaDGwmb4geHNugCXkz
+EtCswfc5jiT8DjMDkgVsGO/WcYj2GWT0K0H+Zf1CmEO9fAoXTLfVBjdumtGILgii
+d/TJe2tOBSWyZz6sVzfac2PvUH5Lm8TNUXuLV5IEdcpySge0vqYQwAyd2EgsTH1e
+mRNSk9NerpmfCFEySRRP3BWMGRhbST1d8M3v9Bq0QFhrxoAF12r6GXBUpp9XcOL5
+pBTcAkA9XI++mfz4pDzyGRGOy4WX+8XtsaVZ/14JklupSLr0Tt7oaNocUhoXB03g
+4B0jUTX0hNnVzCxzJypw6YJ60Zc8z+z8pEF34FWarHec1QbkFuyWxbaTPQ4d2NLH
+8zDxQpMILErWdAgKsRL0d8RFG5fBcleEoBM2kKHMAgnP+1qyDqBgt8zloWbmmblw
+JXMuoePFOgeVcgPrZ3EGJSx+s4+dQGQc6r/GwKLKSWpUvHxTIGug76IX9xmptB+I
+F3xb2QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQANISf3Vi2eueOlzzfnEGGa+CXz
+nvlgUXKv8Gv0/Pbg5uC1BaHTAUgRu5rvrfP9p3Mdj86I/HbE/F4Vkuzqb8/JTWGA
+mG636zAsJRJr0fnkbPma9wVEPSK8MF1QqM6PmKXboixX82TqV1R1sRYG+9hh9W3u
+isDzYDb2ODE0X9M8/3hLS28zdCdtl4zCRK6KB86aGxvkVEj4qDA5l+AbVYevS/SU
+hz1+K/aM0Fi6MZovo5kd/Mof5l05e1TEgCoL1FtFX79r+PYGHJ8/LjtEMkFgwqvG
+CLx2sOV09EHZU27EbVvSs1JYMMXgeAvKaHsVZ51QlSzW4esg/E6z4pw654p8qyK/
+WLXIZ7BMILl1sHYmGqXitnu19puvNks2/+hyqVr0seM5GyQDuwBE8nx6xZzTRxdj
+4TZyN9LuMc9/cKJFvOPqD152bkA2frCLEzYCQreDWwxsWcUHzYrQT+v2SqzP6Ue2
+Xn06HDLx9wBL7Dz6no05SlNS0u1KdvKas6FKZHO+QaKKsBlDmXbMrBTcuUI6OXv2
+6NpVbeyDd0+A23hDiNSgI6zTY6jMidesNExB7rW/bCE4ltPyxFAB+sffyXounODc
+groB5CaS2bv+H1IXJzMMe4LkgQPl1C7G+I3KvJmnrYwmIhLIDuxP82arClIDzccS
+ExRR7ugEg91XCc87Zg==
+-----END CERTIFICATE-----
diff --git a/power/aidl/default/apex/file_contexts b/power/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..3433851
--- /dev/null
+++ b/power/aidl/default/apex/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                                      u:object_r:vendor_file:s0
+/bin/hw/android\.hardware\.power-service\.example           u:object_r:hal_power_default_exec:s0
+/bin/hw/android\.hardware\.power\.stats-service\.example    u:object_r:hal_power_stats_default_exec:s0
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 7c0caf3..66be5f9 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -24,8 +24,8 @@
 cc_binary {
     name: "android.hardware.power.stats-service.example",
     relative_install_path: "hw",
-    init_rc: ["power.stats-default.rc"],
-    vintf_fragments: ["power.stats-default.xml"],
+    init_rc: [":android.hardware.power.stats.rc"],
+    vintf_fragments: [":android.hardware.power.stats.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
@@ -37,3 +37,13 @@
         "PowerStats.cpp",
     ],
 }
+
+filegroup {
+    name: "android.hardware.power.stats.xml",
+    srcs: ["power.stats-default.xml"],
+}
+
+filegroup {
+    name: "android.hardware.power.stats.rc",
+    srcs: ["power.stats-default.rc"],
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 44f9865..c167a6d 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -612,6 +612,9 @@
         EXPECT_EQ(0, cardStatus.applications.size());
     }
 
+    // Give some time for modem to fully power down the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
     /* Test setSimCardPower power up */
     serial = GetRandomSerialNumber();
     radio_v1_6->setSimCardPower_1_6(serial, CardPowerState::POWER_UP);
@@ -624,6 +627,9 @@
                                   ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
                                   ::android::hardware::radio::V1_6::RadioError::SIM_ERR}));
 
+    // Give some time for modem to fully power up the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
     // setSimCardPower_1_6 does not return  until the request is handled. Just verify that we still
     // have CardState::PRESENT after turning the power back on
     if (radioRsp_v1_6->rspInfo.error == ::android::hardware::radio::V1_6::RadioError::NONE) {
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 54c2977..f041865 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -47,6 +47,7 @@
 
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
 
 #define RADIO_SERVICE_SLOT1_NAME "slot1"  // HAL instance name for SIM slot 1 or single SIM device
 #define RADIO_SERVICE_SLOT2_NAME "slot2"  // HAL instance name for SIM slot 2 on dual SIM device
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
index 2cfb8d0..5cc9017 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
@@ -36,7 +36,5 @@
 parcelable SimPortInfo {
   String iccId;
   int logicalSlotId;
-  int portState;
-  const int PORT_STATE_INACTIVE = 0;
-  const int PORT_STATE_ACTIVE = 1;
+  boolean portActive;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
index 0febcd1..0dd8127 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
@@ -37,7 +37,7 @@
   byte sliceServiceType;
   int sliceDifferentiator;
   byte mappedHplmnSst;
-  int mappedHplmnSD;
+  int mappedHplmnSd;
   byte status;
   const byte SERVICE_TYPE_NONE = 0;
   const byte SERVICE_TYPE_EMBB = 1;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
index 7dd1341..8c1fdfa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -39,5 +39,5 @@
   int baseStationId;
   int longitude;
   int latitude;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
index 3991af7..2e384e9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -40,6 +40,6 @@
   int cid;
   int arfcn;
   byte bsic;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
index 9ea0974..c83997e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
@@ -40,7 +40,7 @@
   int pci;
   int tac;
   int earfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   int bandwidth;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
index 865e0dd..6bdfd99 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
@@ -40,7 +40,7 @@
   int pci;
   int tac;
   int nrarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   android.hardware.radio.network.NgranBands[] bands;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 836b5b5..4100805 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -40,7 +40,7 @@
   int cid;
   int cpid;
   int uarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
index f832449..907f30d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -40,7 +40,7 @@
   int cid;
   int psc;
   int uarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index bfb8061..16433be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -42,7 +42,6 @@
   oneway void getCellInfoList(in int serial);
   oneway void getDataRegistrationState(in int serial);
   oneway void getImsRegistrationState(in int serial);
-  oneway void getNeighboringCids(in int serial);
   oneway void getNetworkSelectionMode(in int serial);
   oneway void getOperator(in int serial);
   oneway void getSignalStrength(in int serial);
@@ -50,7 +49,6 @@
   oneway void getVoiceRadioTechnology(in int serial);
   oneway void getVoiceRegistrationState(in int serial);
   oneway void isNrDualConnectivityEnabled(in int serial);
-  oneway void pullLceData(in int serial);
   oneway void responseAcknowledgement();
   oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
   oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index e03e4df..ff95396 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -43,7 +43,6 @@
   oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellInfo[] cellInfo);
   oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult dataRegResponse);
   oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily);
-  oneway void getNeighboringCidsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.NeighboringCell[] cells);
   oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual);
   oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric);
   oneway void getSignalStrengthResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.SignalStrength signalStrength);
@@ -51,7 +50,6 @@
   oneway void getVoiceRadioTechnologyResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioTechnology rat);
   oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult voiceRegResponse);
   oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
-  oneway void pullLceDataResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.LceDataInfo lceInfo);
   oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
index 948a1f6..1e657e5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -41,6 +41,7 @@
   boolean incrementalResults;
   int incrementalResultsPeriodicity;
   String[] mccMncs;
+  const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
   const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MIN = 1;
   const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MAX = 10;
   const int MAX_SEARCH_TIME_RANGE_MIN = 60;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
index cc5a53e..85a0c71 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
@@ -53,11 +53,10 @@
   oneway void iccTransmitApduLogicalChannel(in int serial, in android.hardware.radio.sim.SimApdu message);
   oneway void reportStkServiceIsRunning(in int serial);
   oneway void requestIccSimAuthentication(in int serial, in int authContext, in String authData, in String aid);
-  oneway void requestIsimAuthentication(in int serial, in String challenge);
   oneway void responseAcknowledgement();
-  oneway void sendEnvelope(in int serial, in String command);
+  oneway void sendEnvelope(in int serial, in String contents);
   oneway void sendEnvelopeWithStatus(in int serial, in String contents);
-  oneway void sendTerminalResponseToSim(in int serial, in String commandResponse);
+  oneway void sendTerminalResponseToSim(in int serial, in String contents);
   oneway void setAllowedCarriers(in int serial, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy);
   oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo);
   oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSub);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
index e164257..8e68e30 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -54,7 +54,6 @@
   oneway void iccTransmitApduLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result);
   oneway void reportStkServiceIsRunningResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void requestIccSimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result);
-  oneway void requestIsimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in String response);
   oneway void sendEnvelopeResponse(in android.hardware.radio.RadioResponseInfo info, in String commandResponse);
   oneway void sendEnvelopeWithStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo);
   oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index 579dd29..b373aa5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable CdmaDisplayInfoRecord {
   String alphaBuf;
+  const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 6648358..cc4d3fa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -42,6 +42,7 @@
   android.hardware.radio.voice.CdmaLineControlInfoRecord[] lineCtrl;
   android.hardware.radio.voice.CdmaT53ClirInfoRecord[] clir;
   android.hardware.radio.voice.CdmaT53AudioControlInfoRecord[] audioCtrl;
+  const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
   const int NAME_DISPLAY = 0;
   const int NAME_CALLED_PARTY_NUMBER = 1;
   const int NAME_CALLING_PARTY_NUMBER = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index f3fcb2f..26a7df5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -39,4 +39,5 @@
   byte numberPlan;
   byte pi;
   byte si;
+  const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
index d48102b..744e7ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable CfData {
   android.hardware.radio.voice.CallForwardInfo[] cfInfo;
+  const int NUM_SERVICE_CLASSES = 7;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 4f87c12..af3417d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -37,7 +37,7 @@
   oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.voice.CdmaSignalInfoRecord record);
   oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type);
   oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord);
-  oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecords records);
+  oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecord[] records);
   oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaOtaProvisionStatus status);
   oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList);
   oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
index c5ba293..9517847 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable SsInfoData {
   int[] ssInfo;
+  const int SS_INFO_MAX = 4;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl
deleted file mode 100644
index 2a111c6..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-@VintfStability
-interface ISap {
-  oneway void apduReq(in int token, in android.hardware.radio.SapApduType type, in byte[] command);
-  oneway void connectReq(in int token, in int maxMsgSize);
-  oneway void disconnectReq(in int token);
-  oneway void powerReq(in int token, in boolean state);
-  oneway void resetSimReq(in int token);
-  oneway void setCallback(in android.hardware.radio.ISapCallback sapCallback);
-  oneway void setTransferProtocolReq(in int token, in android.hardware.radio.SapTransferProtocol transferProtocol);
-  oneway void transferAtrReq(in int token);
-  oneway void transferCardReaderStatusReq(in int token);
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl
deleted file mode 100644
index 5ae0392..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-@VintfStability
-interface ISapCallback {
-  oneway void apduResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] apduRsp);
-  oneway void connectResponse(in int token, in android.hardware.radio.SapConnectRsp sapConnectRsp, in int maxMsgSize);
-  oneway void disconnectIndication(in int token, in android.hardware.radio.SapDisconnectType disconnectType);
-  oneway void disconnectResponse(in int token);
-  oneway void errorResponse(in int token);
-  oneway void powerResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-  oneway void resetSimResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-  oneway void statusIndication(in int token, in android.hardware.radio.SapStatus status);
-  oneway void transferAtrResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] atr);
-  oneway void transferCardReaderStatusResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in int cardReaderStatus);
-  oneway void transferProtocolResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
index 10a956e..9bb17fe 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
@@ -52,6 +52,7 @@
   HSPAP = 32768,
   GSM = 65536,
   TD_SCDMA = 131072,
+  IWLAN = 262144,
   LTE_CA = 524288,
   NR = 1048576,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
index d111a0d..f411ca2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
@@ -32,21 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
-enum RadioConst {
-  CDMA_ALPHA_INFO_BUFFER_LENGTH = 64,
-  CDMA_NUMBER_INFO_BUFFER_LENGTH = 81,
-  MAX_RILDS = 3,
-  MAX_SOCKET_NAME_LENGTH = 6,
-  MAX_CLIENT_ID_LENGTH = 2,
-  MAX_DEBUG_SOCKET_NAME_LENGTH = 12,
-  MAX_QEMU_PIPE_NAME_LENGTH = 11,
-  MAX_UUID_LENGTH = 64,
-  CARD_MAX_APPS = 8,
-  CDMA_MAX_NUMBER_OF_INFO_RECS = 10,
-  SS_INFO_MAX = 4,
-  NUM_SERVICE_CLASSES = 7,
-  NUM_TX_POWER_LEVELS = 5,
-  RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8,
-  P2_CONSTANT_NO_P2 = -1,
+@VintfStability
+parcelable RadioConst {
+  const int MAX_RILDS = 3;
+  const int MAX_UUID_LENGTH = 64;
+  const int CARD_MAX_APPS = 8;
+  const int P2_CONSTANT_NO_P2 = -1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl
deleted file mode 100644
index 7e4d246..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-@Backing(type="int") @VintfStability
-enum SapConnectRsp {
-  SUCCESS = 0,
-  CONNECT_FAILURE = 1,
-  MSG_SIZE_TOO_LARGE = 2,
-  MSG_SIZE_TOO_SMALL = 3,
-  CONNECT_OK_CALL_ONGOING = 4,
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl
deleted file mode 100644
index e0d8eb2..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-@Backing(type="int") @VintfStability
-enum SapDisconnectType {
-  GRACEFUL = 0,
-  IMMEDIATE = 1,
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl
deleted file mode 100644
index 715c507..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-@Backing(type="int") @VintfStability
-enum SapStatus {
-  UNKNOWN_ERROR = 0,
-  CARD_RESET = 1,
-  CARD_NOT_ACCESSIBLE = 2,
-  CARD_REMOVED = 3,
-  CARD_INSERTED = 4,
-  RECOVERED = 5,
-}
diff --git a/radio/aidl/android/hardware/radio/ISap.aidl b/radio/aidl/android/hardware/radio/ISap.aidl
deleted file mode 100644
index 1ca4fe7..0000000
--- a/radio/aidl/android/hardware/radio/ISap.aidl
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-import android.hardware.radio.ISapCallback;
-import android.hardware.radio.SapApduType;
-import android.hardware.radio.SapTransferProtocol;
-
-/**
- * Empty top level interface.
- */
-@VintfStability
-oneway interface ISap {
-    /**
-     * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param type APDU command type
-     * @param command CommandAPDU/CommandAPDU7816 parameter depending on type
-     */
-    void apduReq(in int token, in SapApduType type, in byte[] command);
-
-    /**
-     * CONNECT_REQ from SAP 1.1 spec 5.1.1
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param maxMsgSize MaxMsgSize to be used for SIM Access Profile connection
-     */
-    void connectReq(in int token, in int maxMsgSize);
-
-    /**
-     * DISCONNECT_REQ from SAP 1.1 spec 5.1.3
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void disconnectReq(in int token);
-
-    /**
-     * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param state true for on, false for off
-     */
-    void powerReq(in int token, in boolean state);
-
-    /**
-     * RESET_SIM_REQ from SAP 1.1 spec 5.1.14
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void resetSimReq(in int token);
-
-    /**
-     * Set callback that has response and unsolicited indication functions
-     *
-     * @param sapCallback Object containing response and unosolicited indication callbacks
-     */
-    void setCallback(in ISapCallback sapCallback);
-
-    /**
-     * SET_TRANSPORT_PROTOCOL_REQ from SAP 1.1 spec 5.1.20
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param transferProtocol Transport Protocol
-     */
-    void setTransferProtocolReq(in int token, in SapTransferProtocol transferProtocol);
-
-    /**
-     * TRANSFER_ATR_REQ from SAP 1.1 spec 5.1.8
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void transferAtrReq(in int token);
-
-    /**
-     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.17
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void transferCardReaderStatusReq(in int token);
-}
diff --git a/radio/aidl/android/hardware/radio/ISapCallback.aidl b/radio/aidl/android/hardware/radio/ISapCallback.aidl
deleted file mode 100644
index 00e543b..0000000
--- a/radio/aidl/android/hardware/radio/ISapCallback.aidl
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-import android.hardware.radio.SapConnectRsp;
-import android.hardware.radio.SapDisconnectType;
-import android.hardware.radio.SapResultCode;
-import android.hardware.radio.SapStatus;
-
-@VintfStability
-oneway interface ISapCallback {
-    /**
-     * TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED
-     * @param apduRsp APDU Response. Valid only if command was processed correctly and no error
-     *        occurred.
-     */
-    void apduResponse(in int token, in SapResultCode resultCode, in byte[] apduRsp);
-
-    /**
-     * CONNECT_RESP from SAP 1.1 spec 5.1.2
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param sapConnectRsp Connection Status
-     * @param maxMsgSize MaxMsgSize supported by server if request cannot be fulfilled.
-     *        Valid only if connectResponse is SapConnectResponse:MSG_SIZE_TOO_LARGE.
-     */
-    void connectResponse(in int token, in SapConnectRsp sapConnectRsp, in int maxMsgSize);
-
-    /**
-     * DISCONNECT_IND from SAP 1.1 spec 5.1.5
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param disconnectType Disconnect Type to indicate if shutdown is graceful or immediate
-     */
-    void disconnectIndication(in int token, in SapDisconnectType disconnectType);
-
-    /**
-     * DISCONNECT_RESP from SAP 1.1 spec 5.1.4
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     */
-    void disconnectResponse(in int token);
-
-    /**
-     * ERROR_RESP from SAP 1.1 spec 5.1.19
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     */
-    void errorResponse(in int token);
-
-    /**
-     * POWER_SIM_OFF_RESP and POWER_SIM_ON_RESP from SAP 1.1 spec 5.1.11 + 5.1.13
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE, (possible only for power on req)
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF, (possible only for power off req)
-     *        SapResultCode:CARD_REMOVED,
-     *        SapResultCode:CARD_ALREADY_POWERED_ON (possible only for power on req)
-     */
-    void powerResponse(in int token, in SapResultCode resultCode);
-
-    /**
-     * RESET_SIM_RESP from SAP 1.1 spec 5.1.15
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED
-     */
-    void resetSimResponse(in int token, in SapResultCode resultCode);
-
-    /**
-     * STATUS_IND from SAP 1.1 spec 5.1.16
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param status Parameter to indicate reason for the status change.
-     */
-    void statusIndication(in int token, in SapStatus status);
-
-    /**
-     * TRANSFER_ATR_RESP from SAP 1.1 spec 5.1.9
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED,
-     *        SapResultCode:DATA_NOT_AVAILABLE
-     * @param atr Answer to Reset from the subscription module. Included only if no error occurred,
-     *        otherwise empty.
-     */
-    void transferAtrResponse(in int token, in SapResultCode resultCode, in byte[] atr);
-
-    /**
-     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.18
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE
-     *        SapResultCode:DATA_NOT_AVAILABLE
-     * @param cardReaderStatus Card Reader Status coded as described in 3GPP TS 11.14 Section 12.33
-     *        and TS 31.111 Section 8.33
-     */
-    void transferCardReaderStatusResponse(
-            in int token, in SapResultCode resultCode, in int cardReaderStatus);
-
-    /**
-     * SET_TRANSPORT_PROTOCOL_RESP from SAP 1.1 spec 5.1.21
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS
-     *        SapResultCode:NOT_SUPPORTED
-     */
-    void transferProtocolResponse(in int token, in SapResultCode resultCode);
-}
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 719837d..b8fbf9b 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -39,6 +39,7 @@
     HSPAP = 1 << RadioTechnology.HSPAP,
     GSM = 1 << RadioTechnology.GSM,
     TD_SCDMA = 1 << RadioTechnology.TD_SCDMA,
+    IWLAN = 1 << RadioTechnology.IWLAN,
     LTE_CA = 1 << RadioTechnology.LTE_CA,
     /**
      * 5G NR. This is only use in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl
index 2e1bcf0..cd03f84 100644
--- a/radio/aidl/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/android/hardware/radio/RadioConst.aidl
@@ -17,24 +17,12 @@
 package android.hardware.radio;
 
 @VintfStability
-@Backing(type="int")
-enum RadioConst {
-    CDMA_ALPHA_INFO_BUFFER_LENGTH = 64,
-    CDMA_NUMBER_INFO_BUFFER_LENGTH = 81,
-    MAX_RILDS = 3,
-    MAX_SOCKET_NAME_LENGTH = 6,
-    MAX_CLIENT_ID_LENGTH = 2,
-    MAX_DEBUG_SOCKET_NAME_LENGTH = 12,
-    MAX_QEMU_PIPE_NAME_LENGTH = 11,
-    MAX_UUID_LENGTH = 64,
-    CARD_MAX_APPS = 8,
-    CDMA_MAX_NUMBER_OF_INFO_RECS = 10,
-    SS_INFO_MAX = 4,
-    NUM_SERVICE_CLASSES = 7,
-    NUM_TX_POWER_LEVELS = 5,
-    RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8,
+parcelable RadioConst {
+    const int MAX_RILDS = 3;
+    const int MAX_UUID_LENGTH = 64;
+    const int CARD_MAX_APPS = 8;
     /**
      * No P2 value is provided
      */
-    P2_CONSTANT_NO_P2 = -1,
+    const int P2_CONSTANT_NO_P2 = -1;
 }
diff --git a/radio/aidl/android/hardware/radio/SapApduType.aidl b/radio/aidl/android/hardware/radio/SapApduType.aidl
deleted file mode 100644
index f697e58..0000000
--- a/radio/aidl/android/hardware/radio/SapApduType.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapApduType {
-    APDU,
-    APDU7816,
-}
diff --git a/radio/aidl/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/android/hardware/radio/SapConnectRsp.aidl
deleted file mode 100644
index d2046d2..0000000
--- a/radio/aidl/android/hardware/radio/SapConnectRsp.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapConnectRsp {
-    SUCCESS,
-    CONNECT_FAILURE,
-    MSG_SIZE_TOO_LARGE,
-    MSG_SIZE_TOO_SMALL,
-    CONNECT_OK_CALL_ONGOING,
-}
diff --git a/radio/aidl/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/android/hardware/radio/SapDisconnectType.aidl
deleted file mode 100644
index 30a04bd..0000000
--- a/radio/aidl/android/hardware/radio/SapDisconnectType.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapDisconnectType {
-    GRACEFUL,
-    IMMEDIATE,
-}
diff --git a/radio/aidl/android/hardware/radio/SapResultCode.aidl b/radio/aidl/android/hardware/radio/SapResultCode.aidl
deleted file mode 100644
index db87374..0000000
--- a/radio/aidl/android/hardware/radio/SapResultCode.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapResultCode {
-    SUCCESS,
-    GENERIC_FAILURE,
-    CARD_NOT_ACCESSSIBLE,
-    CARD_ALREADY_POWERED_OFF,
-    CARD_REMOVED,
-    CARD_ALREADY_POWERED_ON,
-    DATA_NOT_AVAILABLE,
-    NOT_SUPPORTED,
-}
diff --git a/radio/aidl/android/hardware/radio/SapStatus.aidl b/radio/aidl/android/hardware/radio/SapStatus.aidl
deleted file mode 100644
index 0a6b4a7..0000000
--- a/radio/aidl/android/hardware/radio/SapStatus.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapStatus {
-    UNKNOWN_ERROR,
-    CARD_RESET,
-    CARD_NOT_ACCESSIBLE,
-    CARD_REMOVED,
-    CARD_INSERTED,
-    RECOVERED,
-}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
deleted file mode 100644
index 7f385de..0000000
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio;
-
-@VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
-}
diff --git a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
index 78f1309..54b9890 100644
--- a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
@@ -34,18 +34,10 @@
      * Logical slot id is identifier of the active slot
      */
     int logicalSlotId;
-    /*
-     * Port is Inactive
-     * Inactive means logical modem is no longer associated to the port
-     */
-    const int PORT_STATE_INACTIVE = 0;
-    /*
-     * Port is Active
-     * Active means logical modem is associated to the port
-     */
-    const int PORT_STATE_ACTIVE = 1;
     /**
-     * Port state in the slot. Values are portState.[PORT_STATE_INACTIVE, PORT_STATE_ACTIVE].
+     * Port active status in the slot.
+     * Inactive means logical modem is no longer associated to the port.
+     * Active means logical modem is associated to the port.
      */
-    int portState;
+    boolean portActive;
 }
diff --git a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
index dd315e8..0943031 100644
--- a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
@@ -83,7 +83,7 @@
      * value. A value of -1 indicates that there is no corresponding SliceInfo of the HPLMN.
      * See: 3GPP TS 24.501 Section 9.11.2.8.
      */
-    int mappedHplmnSD;
+    int mappedHplmnSd;
     /**
      * Field to indicate the current status of the slice.
      * Values are STATUS_
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index e271e50..ae6fda4 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityCdma {
@@ -44,5 +44,8 @@
      * (corresponding to a range of -90 to +90 degrees). INT_MAX if unknown
      */
     int latitude;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
index 7b711ad..75a96e8 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityGsm {
@@ -44,7 +44,10 @@
      * 6-bit Base Station Identity Code, 0xFF if unknown
      */
     byte bsic;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
index d4f83a3..ae52cf2 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
@@ -16,9 +16,9 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
 import android.hardware.radio.network.EutranBands;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityLte {
@@ -46,7 +46,10 @@
      * 18-bit LTE Absolute RF Channel Number; this value must be valid
      */
     int earfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Cell bandwidth, in kHz.
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
index dfccbf7..73a56ea 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.NgranBands;
+import android.hardware.radio.network.OperatorInfo;
 
 /**
  * The CellIdentity structure should be reported once for each element of the PLMN-IdentityInfoList
@@ -55,7 +55,10 @@
      * This value must be valid.
      */
     int nrarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
deleted file mode 100644
index 540014a..0000000
--- a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 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.radio.network;
-
-@VintfStability
-parcelable CellIdentityOperatorNames {
-    /**
-     * Long alpha operator name string or enhanced operator name string.
-     */
-    String alphaLong;
-    /**
-     * Short alpha operator name string or enhanced operator name string.
-     */
-    String alphaShort;
-}
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 99c8151..5b00df1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityTdscdma {
@@ -45,7 +45,10 @@
      * 16-bit UMTS Absolute RF Channel Number defined in TS 25.102 5.4.4; this value must be valid.
      */
     int uarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell.
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
index 302be96..bf4d6cb 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityWcdma {
@@ -45,7 +45,10 @@
      * 16-bit UMTS Absolute RF Channel Number; this value must be valid.
      */
     int uarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell.
      */
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index ffc97f3..1081a75 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -114,15 +114,6 @@
     void getImsRegistrationState(in int serial);
 
     /**
-     * Request neighboring cell id in GSM network
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioNetworkResponse.getNeighboringCidsResponse()
-     */
-    void getNeighboringCids(in int serial);
-
-    /**
      * Query current network selection mode
      *
      * @param serial Serial number of request.
@@ -187,15 +178,6 @@
     void isNrDualConnectivityEnabled(in int serial);
 
     /**
-     * Pull LCE service for capacity information.
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioNetworkResponse.pullLceDataResponse()
-     */
-    void pullLceData(in int serial);
-
-    /**
      * When response type received from a radio indication or radio response is
      * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively,
      * acknowledge the receipt of those messages by sending responseAcknowledgement().
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index ae2646d..429b5a8 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -179,25 +179,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param cells Vector of neighboring radio cell
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:NO_MEMORY
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:MODEM_ERR
-     *   RadioError:NO_NETWORK_FOUND
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     */
-    void getNeighboringCidsResponse(in RadioResponseInfo info, in NeighboringCell[] cells);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      * @param selection false for automatic selection, true for manual selection
      *
      * Valid errors returned:
@@ -299,23 +280,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param lceInfo LceDataInfo indicating LCE data
-     *
-     * Valid errors returned:
-     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:LCE_NOT_SUPPORTED
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_MEMORY
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     *   RadioError:SIM_ABSENT
-     */
-    void pullLceDataResponse(in RadioResponseInfo info, in LceDataInfo lceInfo);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
index ec8aa95..7cea1de 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -20,6 +20,8 @@
 
 @VintfStability
 parcelable NetworkScanRequest {
+    const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
+
     const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MIN = 1;
     const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MAX = 10;
 
@@ -50,7 +52,7 @@
     int interval;
     /**
      * Networks with bands/channels to scan.
-     * Maximum length of the vector is RadioConst:RADIO_ACCESS_SPECIFIER_MAX_SIZE.
+     * Maximum length of the vector is RADIO_ACCESS_SPECIFIER_MAX_SIZE.
      */
     RadioAccessSpecifier[] specifiers;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index bd681e7..312182e 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -32,10 +32,11 @@
      */
     RegState regState;
     /**
-     * Indicates the available voice radio technology, valid values as defined by RadioTechnology,
-     * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on
-     * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig
-     * elements through IRadioNetwork::currentPhysicalChannelConfigs.
+     * Indicates the radio technology (except LTE_CA, which is no longer a valid value), which
+     * must not be UNKNOWN if regState is REG_HOME, REG_ROAMING, NOT_REG_MT_NOT_SEARCHING_OP_EM,
+     * NOT_REG_MT_SEARCHING_OP_EM, REG_DENIED_EM, or UNKNOWN_EM.
+     * When the device is on carrier aggregation, vendor RIL service must properly report multiple
+     * PhysicalChannelConfig elements through IRadioNetwork::currentPhysicalChannelConfigs.
      */
     RadioTechnology rat;
     /**
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 902c90c..c731caf 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -262,17 +262,6 @@
             in int serial, in int authContext, in String authData, in String aid);
 
     /**
-     * Request the ISIM application on the UICC to perform AKA challenge/response algorithm
-     * for IMS authentication
-     *
-     * @param serial Serial number of request.
-     * @param challenge challenge string in Base64 format
-     *
-     * Response function is IRadioSimResponse.requestIsimAuthenticationResponse()
-     */
-    void requestIsimAuthentication(in int serial, in String challenge);
-
-    /**
      * When response type received from a radio indication or radio response is
      * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively,
      * acknowledge the receipt of those messages by sending responseAcknowledgement().
@@ -284,11 +273,11 @@
      * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111
      *
      * @param serial Serial number of request.
-     * @param command SAT/USAT command in hexadecimal format string starting with command tag
+     * @param contents SAT/USAT command in hexadecimal format string starting with command tag
      *
      * Response function is IRadioSimResponse.sendEnvelopeResponse()
      */
-    void sendEnvelope(in int serial, in String command);
+    void sendEnvelope(in int serial, in String contents);
 
     /**
      * Requests to send a SAT/USAT envelope command to SIM. The SAT/USAT envelope command refers to
@@ -309,12 +298,12 @@
      * Requests to send a terminal response to SIM for a received proactive command
      *
      * @param serial Serial number of request.
-     * @param commandResponse SAT/USAT response in hexadecimal format string starting with
+     * @param contents SAT/USAT response in hexadecimal format string starting with
      *        first byte of response data
      *
      * Response function is IRadioSimResponse.sendTerminalResponseResponseToSim()
      */
-    void sendTerminalResponseToSim(in int serial, in String commandResponse);
+    void sendTerminalResponseToSim(in int serial, in String contents);
 
     /**
      * Set carrier restrictions. Expected modem behavior:
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index dcc7029..750a29a 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -365,24 +365,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param response response string of the challenge/response algo for ISIM auth in base64 format
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_MEMORY
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:SIM_ABSENT
-     */
-    void requestIsimAuthenticationResponse(in RadioResponseInfo info, in String response);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      * @param commandResponse SAT/USAT response in hexadecimal format string starting with first
      *        byte of response
      *
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index 18a1ce4..ac66237 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -25,8 +25,9 @@
  */
 @VintfStability
 parcelable CdmaDisplayInfoRecord {
+    const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
     /**
-     * Max length = RadioConst:CDMA_ALPHA_INFO_BUFFER_LENGTH
+     * Max length = CDMA_ALPHA_INFO_BUFFER_LENGTH
      */
     String alphaBuf;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
index af37dac..6920462 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -25,7 +25,11 @@
 import android.hardware.radio.voice.CdmaT53ClirInfoRecord;
 
 @VintfStability
+/**
+ * Max length of CdmaInformationRecords[] is CDMA_MAX_NUMBER_OF_INFO_RECS
+ */
 parcelable CdmaInformationRecord {
+    const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
     /**
      * Names of the CDMA info records (C.S0005 section 3.7.5)
      */
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index 41ce08f..265bf67 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -23,8 +23,9 @@
  */
 @VintfStability
 parcelable CdmaNumberInfoRecord {
+    const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
     /**
-     * Max length = RadioConst::CDMA_NUMBER_INFO_BUFFER_LENGTH
+     * Max length = CDMA_NUMBER_INFO_BUFFER_LENGTH
      */
     String number;
     byte numberType;
diff --git a/radio/aidl/android/hardware/radio/voice/CfData.aidl b/radio/aidl/android/hardware/radio/voice/CfData.aidl
index 8d7c4bd..f28c7c8 100644
--- a/radio/aidl/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CfData.aidl
@@ -20,9 +20,10 @@
 
 @VintfStability
 parcelable CfData {
+    const int NUM_SERVICE_CLASSES = 7;
     /**
      * This is the response data for SS request to query call forward status.
-     * See getCallForwardStatus(). Max size = RadioConst:NUM_SERVICE_CLASSES.
+     * See getCallForwardStatus(). Max size = NUM_SERVICE_CLASSES.
      */
     CallForwardInfo[] cfInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 81640f3..25e87b3 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -18,7 +18,7 @@
 
 import android.hardware.radio.RadioIndicationType;
 import android.hardware.radio.voice.CdmaCallWaiting;
-import android.hardware.radio.voice.CdmaInformationRecords;
+import android.hardware.radio.voice.CdmaInformationRecord;
 import android.hardware.radio.voice.CdmaOtaProvisionStatus;
 import android.hardware.radio.voice.CdmaSignalInfoRecord;
 import android.hardware.radio.voice.EmergencyNumber;
@@ -67,9 +67,10 @@
      * Indicates when CDMA radio receives one or more info recs.
      *
      * @param type Type of radio indication
-     * @param records New Cdma Information
+     * @param records New CDMA information records.
+     *        Max length is RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
      */
-    void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecords records);
+    void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecord[] records);
 
     /**
      * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call.
diff --git a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
index 40af393..d562925 100644
--- a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
@@ -18,11 +18,12 @@
 
 @VintfStability
 parcelable SsInfoData {
+    const int SS_INFO_MAX = 4;
     /**
      * This is the response data for all of the SS GET/SET Radio requests.
      * E.g. IRadioVoice.getClir() returns two ints, so first two values of ssInfo[] will be used for
      * response if serviceType is SS_CLIR and requestType is SS_INTERROGATION.
-     * Max size = RadioConst:SS_INFO_MAX
+     * Max size = SS_INFO_MAX
      */
     int[] ssInfo;
 }
diff --git a/security/keymint/aidl/OWNERS b/security/OWNERS
similarity index 100%
rename from security/keymint/aidl/OWNERS
rename to security/OWNERS
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 6f2f189..3cbffbf 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -78,6 +78,7 @@
                                       .Digest(Digest::SHA_2_256)
                                       .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -106,6 +107,7 @@
                                       .EcdsaSigningKey(EcCurve::P_256)
                                       .Digest(Digest::SHA_2_256)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -135,6 +137,7 @@
                                       .Digest(Digest::SHA_2_256)
                                       .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -192,6 +195,7 @@
                                       .EcdsaSigningKey(EcCurve::P_256)
                                       .Digest(Digest::SHA_2_256)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -252,14 +256,16 @@
 
     for (const KeyParameter& tag : attestation_id_tags) {
         SCOPED_TRACE(testing::Message() << "+tag-" << tag);
-        AuthorizationSetBuilder builder = AuthorizationSetBuilder()
-                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                  .EcdsaSigningKey(EcCurve::P_256)
-                                                  .Digest(Digest::SHA_2_256)
-                                                  .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                                  .AttestationChallenge("challenge")
-                                                  .AttestationApplicationId("foo")
-                                                  .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .EcdsaSigningKey(EcCurve::P_256)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                        .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                        .AttestationChallenge("challenge")
+                        .AttestationApplicationId("foo")
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
         builder.push_back(tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
 
@@ -322,14 +328,16 @@
 
     for (const KeyParameter& invalid_tag : attestation_id_tags) {
         SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
-        AuthorizationSetBuilder builder = AuthorizationSetBuilder()
-                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                  .EcdsaSigningKey(EcCurve::P_256)
-                                                  .Digest(Digest::SHA_2_256)
-                                                  .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                                  .AttestationChallenge("challenge")
-                                                  .AttestationApplicationId("foo")
-                                                  .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .EcdsaSigningKey(EcCurve::P_256)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                        .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                        .AttestationChallenge("challenge")
+                        .AttestationApplicationId("foo")
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
         // Add the tag that doesn't match the local device's real ID.
         builder.push_back(invalid_tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 95e25d6..919d79f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1627,13 +1627,13 @@
  */
 TEST_P(NewKeyGenerationTest, EcdsaAttestationUniqueId) {
     auto get_unique_id = [this](const std::string& app_id, uint64_t datetime,
-                                vector<uint8_t>* unique_id) {
+                                vector<uint8_t>* unique_id, bool reset = false) {
         auto challenge = "hello";
         auto subject = "cert subj 2";
         vector<uint8_t> subject_der(make_name_from_str(subject));
         uint64_t serial_int = 0x1010;
         vector<uint8_t> serial_blob(build_serial_blob(serial_int));
-        const AuthorizationSetBuilder builder =
+        AuthorizationSetBuilder builder =
                 AuthorizationSetBuilder()
                         .Authorization(TAG_NO_AUTH_REQUIRED)
                         .Authorization(TAG_INCLUDE_UNIQUE_ID)
@@ -1645,6 +1645,9 @@
                         .AttestationApplicationId(app_id)
                         .Authorization(TAG_CREATION_DATETIME, datetime)
                         .SetDefaultValidity();
+        if (reset) {
+            builder.Authorization(TAG_RESET_SINCE_ID_ROTATION);
+        }
 
         ASSERT_EQ(ErrorCode::OK, GenerateKey(builder));
         ASSERT_GT(key_blob_.size(), 0U);
@@ -1706,6 +1709,11 @@
     vector<uint8_t> unique_id8;
     get_unique_id(app_id, min_date - 1, &unique_id8);
     EXPECT_NE(unique_id, unique_id8);
+
+    // Marking RESET_SINCE_ID_ROTATION should give a different unique ID.
+    vector<uint8_t> unique_id9;
+    get_unique_id(app_id, cert_date, &unique_id9, /* reset_id = */ true);
+    EXPECT_NE(unique_id, unique_id9);
 }
 
 /*
diff --git a/security/keymint/support/OWNERS b/security/keymint/support/OWNERS
deleted file mode 100644
index a93b171..0000000
--- a/security/keymint/support/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbires@google.com
-jdanis@google.com
-seleneh@google.com
-swillden@google.com
diff --git a/security/secureclock/aidl/OWNERS b/security/secureclock/aidl/OWNERS
deleted file mode 100644
index a93b171..0000000
--- a/security/secureclock/aidl/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbires@google.com
-jdanis@google.com
-seleneh@google.com
-swillden@google.com
diff --git a/security/sharedsecret/aidl/OWNERS b/security/sharedsecret/aidl/OWNERS
deleted file mode 100644
index a93b171..0000000
--- a/security/sharedsecret/aidl/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbires@google.com
-jdanis@google.com
-seleneh@google.com
-swillden@google.com
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/1.0/vts/functional/OWNERS
+++ b/sensors/1.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
index aca6961..c69f32a 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
@@ -25,7 +25,7 @@
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SensorInfo;
 
-void SensorsHidlEnvironmentV1_0::HidlTearDown() {
+void SensorsHidlEnvironmentV1_0::TearDown() {
     mStopThread = true;
     if (mPollThread.joinable()) {
         mPollThread.detach();
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index 168777d..b802e6c 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
 #define ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
 
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <android/hardware/sensors/1.0/types.h>
@@ -30,13 +30,13 @@
 
 class SensorsHidlTest;
 class SensorsHidlEnvironmentV1_0
-    : public SensorsHidlEnvironmentBase<::android::hardware::sensors::V1_0::Event> {
+    : public SensorsVtsEnvironmentBase<::android::hardware::sensors::V1_0::Event> {
   public:
-    void HidlTearDown() override;
+    void TearDown() override;
 
     using Event = ::android::hardware::sensors::V1_0::Event;
     SensorsHidlEnvironmentV1_0(const std::string& service_name)
-        : SensorsHidlEnvironmentBase(service_name) {}
+        : SensorsVtsEnvironmentBase(service_name) {}
 
   private:
     friend SensorsHidlTest;
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index d46cf5a..e4fa969 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -39,12 +39,12 @@
   public:
     virtual void SetUp() override {
         mEnvironment = new SensorsHidlEnvironmentV1_0(GetParam());
-        mEnvironment->HidlSetUp();
+        mEnvironment->SetUp();
         // Ensure that we have a valid environment before performing tests
         ASSERT_NE(S(), nullptr);
     }
 
-    virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+    virtual void TearDown() override { mEnvironment->TearDown(); }
 
   protected:
     SensorInfo defaultSensorByType(SensorType type) override;
@@ -81,7 +81,7 @@
 
     inline sp<ISensors>& S() { return mEnvironment->sensors; }
 
-    SensorsHidlEnvironmentBase<Event>* getEnvironment() override { return mEnvironment; }
+    SensorsVtsEnvironmentBase<Event>* getEnvironment() override { return mEnvironment; }
 
   private:
     // Test environment for sensors HAL.
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.0/vts/functional/OWNERS
+++ b/sensors/2.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index e212423..d7d061a 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -256,8 +256,8 @@
     // Clear the active direct connections so they are not stopped during TearDown
     auto handles = mDirectChannelHandles;
     mDirectChannelHandles.clear();
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.1/vts/functional/OWNERS
+++ b/sensors/2.1/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/common/utils/convertV2_1.h b/sensors/common/utils/convertV2_1.h
index 9231011..00359043 100644
--- a/sensors/common/utils/convertV2_1.h
+++ b/sensors/common/utils/convertV2_1.h
@@ -77,6 +77,25 @@
     return reinterpret_cast<const hidl_vec<V1_0::SensorInfo>&>(infos);
 }
 
+inline void convertToSensor(const V2_1::SensorInfo& src, sensor_t* dst) {
+    dst->name = strdup(src.name.c_str());
+    dst->vendor = strdup(src.vendor.c_str());
+    dst->version = src.version;
+    dst->handle = src.sensorHandle;
+    dst->type = (int)src.type;
+    dst->maxRange = src.maxRange;
+    dst->resolution = src.resolution;
+    dst->power = src.power;
+    dst->minDelay = src.minDelay;
+    dst->fifoReservedEventCount = src.fifoReservedEventCount;
+    dst->fifoMaxEventCount = src.fifoMaxEventCount;
+    dst->stringType = strdup(src.typeAsString.c_str());
+    dst->requiredPermission = strdup(src.requiredPermission.c_str());
+    dst->maxDelay = src.maxDelay;
+    dst->flags = src.flags;
+    dst->reserved[0] = dst->reserved[1] = 0;
+}
+
 inline void convertFromSensorEvent(const sensors_event_t& src, V2_1::Event* dst) {
     switch ((SensorType)src.type) {
         case SensorType::HINGE_ANGLE:
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
index a8c2513..d395820 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
@@ -103,7 +103,7 @@
     return succeed;
 }
 
-void SensorsHidlEnvironmentV2_X::HidlTearDown() {
+void SensorsHidlEnvironmentV2_X::TearDown() {
     mStopThread = true;
 
     if (mEventQueueFlag != nullptr) {
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
index 01f451f..5fe4d8b 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
@@ -18,7 +18,7 @@
 #define ANDROID_SENSORS_HIDL_ENVIRONMENT_V2_X_H
 
 #include "ISensorsWrapper.h"
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/2.1/ISensors.h>
 #include <android/hardware/sensors/2.1/types.h>
@@ -46,14 +46,14 @@
 };
 
 class SensorsHidlEnvironmentV2_X
-    : public SensorsHidlEnvironmentBase<::android::hardware::sensors::V2_1::Event> {
+    : public SensorsVtsEnvironmentBase<::android::hardware::sensors::V2_1::Event> {
   public:
-    virtual void HidlTearDown() override;
+    virtual void TearDown() override;
 
   protected:
     friend SensorsHidlTest;
     SensorsHidlEnvironmentV2_X(const std::string& service_name)
-        : SensorsHidlEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
+        : SensorsVtsEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
 
     /**
      * Resets the HAL with new FMQs and a new Event Flag
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index ea5dc70..7e22b19 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -170,12 +170,12 @@
   public:
     virtual void SetUp() override {
         mEnvironment = new SensorsHidlEnvironmentV2_X(GetParam());
-        mEnvironment->HidlSetUp();
+        mEnvironment->SetUp();
         // Ensure that we have a valid environment before performing tests
         ASSERT_NE(getSensors(), nullptr);
     }
 
-    virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+    virtual void TearDown() override { mEnvironment->TearDown(); }
 
   protected:
     SensorInfoType defaultSensorByType(SensorTypeVersion type) override;
@@ -216,7 +216,7 @@
 
     inline sp<ISensorsWrapperBase>& getSensors() { return mEnvironment->mSensors; }
 
-    SensorsHidlEnvironmentBase<EventType>* getEnvironment() override { return mEnvironment; }
+    SensorsVtsEnvironmentBase<EventType>* getEnvironment() override { return mEnvironment; }
 
     // Test helpers
     void runSingleFlushTest(const std::vector<SensorInfoType>& sensors, bool activateSensor,
@@ -530,32 +530,31 @@
     // Create a new environment that calls initialize()
     std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
             std::make_unique<SensorsHidlEnvironmentTest>(GetParam());
-    newEnv->HidlSetUp();
+    newEnv->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if setting up the new environment failed
     }
 
     activateAllSensors(true);
     // Verify that the old environment does not receive any events
-    EXPECT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    EXPECT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
     // Verify that the new event queue receives sensor events
-    EXPECT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, newEnv.get(), newEnv.get()).size(),
-              kNumEvents);
+    EXPECT_GE(newEnv.get()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
     activateAllSensors(false);
 
     // Cleanup the test environment
-    newEnv->HidlTearDown();
+    newEnv->TearDown();
 
     // Restore the test environment for future tests
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
 
     // Ensure that the original environment is receiving events
     activateAllSensors(true);
-    EXPECT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+    EXPECT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
     activateAllSensors(false);
 }
 
@@ -565,21 +564,21 @@
     // Verify that events are received
     constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
     constexpr int32_t kNumEvents = 1;
-    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
 
     // Clear the active sensor handles so they are not disabled during TearDown
     auto handles = mSensorHandles;
     mSensorHandles.clear();
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
 
     // Verify no events are received until sensors are re-activated
-    ASSERT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    ASSERT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
     activateAllSensors(true);
-    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
 
     // Disable sensors
     activateAllSensors(false);
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
deleted file mode 100644
index 19dfbe5..0000000
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
-#define ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
-
-#include <gtest/gtest.h>
-
-#include <atomic>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-template <class Event>
-class IEventCallback {
-  public:
-    virtual ~IEventCallback() = default;
-    virtual void onEvent(const Event& event) = 0;
-};
-
-template <class Event>
-class SensorsHidlEnvironmentBase {
-  public:
-    virtual void HidlSetUp() {
-        ASSERT_TRUE(resetHal()) << "could not get hidl service";
-
-        mCollectionEnabled = false;
-        startPollingThread();
-
-        // In case framework just stopped for test and there is sensor events in the pipe,
-        // wait some time for those events to be cleared to avoid them messing up the test.
-        std::this_thread::sleep_for(std::chrono::seconds(3));
-    }
-
-    virtual void HidlTearDown() = 0;
-
-    // Get and clear all events collected so far (like "cat" shell command).
-    // If output is nullptr, it clears all collected events.
-    void catEvents(std::vector<Event>* output) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        if (output) {
-            output->insert(output->end(), mEvents.begin(), mEvents.end());
-        }
-        mEvents.clear();
-    }
-
-    // set sensor event collection status
-    void setCollection(bool enable) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCollectionEnabled = enable;
-    }
-
-    void registerCallback(IEventCallback<Event>* callback) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCallback = callback;
-    }
-
-    void unregisterCallback() {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCallback = nullptr;
-    }
-
-   protected:
-     SensorsHidlEnvironmentBase(const std::string& service_name)
-         : mCollectionEnabled(false), mCallback(nullptr) {
-         mServiceName = service_name;
-     }
-     virtual ~SensorsHidlEnvironmentBase(){};
-
-     void addEvent(const Event& ev) {
-         std::lock_guard<std::mutex> lock(mEventsMutex);
-         if (mCollectionEnabled) {
-             mEvents.push_back(ev);
-         }
-
-         if (mCallback != nullptr) {
-             mCallback->onEvent(ev);
-         }
-     }
-
-     virtual void startPollingThread() = 0;
-     virtual bool resetHal() = 0;
-
-     std::string mServiceName;
-     bool mCollectionEnabled;
-     std::atomic_bool mStopThread;
-     std::thread mPollThread;
-     std::vector<Event> mEvents;
-     std::mutex mEventsMutex;
-
-     IEventCallback<Event>* mCallback;
-
-     GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase<Event>);
-};
-
-#endif  // ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index af14009..f3cbd78 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -18,8 +18,8 @@
 #define ANDROID_SENSORS_HIDL_TEST_BASE_H
 
 #include "sensors-vts-utils/SensorEventsChecker.h"
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
 #include "sensors-vts-utils/SensorsTestSharedMemory.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <android/hardware/sensors/1.0/types.h>
@@ -163,7 +163,7 @@
         : mAccelNormChecker(Vec3NormChecker<EventType>::byNominal(GRAVITY_EARTH, 1.0f /*m/s^2*/)),
           mGyroNormChecker(Vec3NormChecker<EventType>::byNominal(0.f, 0.1f /*rad/s*/)) {}
 
-    virtual SensorsHidlEnvironmentBase<EventType>* getEnvironment() = 0;
+    virtual SensorsVtsEnvironmentBase<EventType>* getEnvironment() = 0;
 
     virtual void SetUp() override {}
 
@@ -198,49 +198,6 @@
                                             RateLevel rate,
                                             ISensors::configDirectReport_cb _hidl_cb) = 0;
 
-    std::vector<EventType> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
-                                         bool clearBeforeStart = true,
-                                         bool changeCollection = true) {
-        return collectEvents(timeLimitUs, nEventLimit, getEnvironment(), clearBeforeStart,
-                             changeCollection);
-    }
-
-    std::vector<EventType> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
-                                         SensorsHidlEnvironmentBase<EventType>* environment,
-                                         bool clearBeforeStart = true,
-                                         bool changeCollection = true) {
-        std::vector<EventType> events;
-        constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
-
-        ALOGI("collect max of %zu events for %d us, clearBeforeStart %d", nEventLimit, timeLimitUs,
-              clearBeforeStart);
-
-        if (changeCollection) {
-            environment->setCollection(true);
-        }
-        if (clearBeforeStart) {
-            environment->catEvents(nullptr);
-        }
-
-        while (timeLimitUs > 0) {
-            useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
-            usleep(duration);
-            timeLimitUs -= duration;
-
-            environment->catEvents(&events);
-            if (events.size() >= nEventLimit) {
-                break;
-            }
-            ALOGV("time to go = %d, events to go = %d", (int)timeLimitUs,
-                  (int)(nEventLimit - events.size()));
-        }
-
-        if (changeCollection) {
-            environment->setCollection(false);
-        }
-        return events;
-    }
-
     void testStreamingOperation(SensorTypeVersion type, std::chrono::nanoseconds samplingPeriod,
                                 std::chrono::seconds duration,
                                 const SensorEventsChecker<EventType>& checker) {
@@ -268,7 +225,7 @@
 
         ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
         ASSERT_EQ(activate(handle, 1), Result::OK);
-        events = collectEvents(minTimeUs, minNEvent, getEnvironment(), true /*clearBeforeStart*/);
+        events = getEnvironment()->collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
         ASSERT_EQ(activate(handle, 0), Result::OK);
 
         ALOGI("Collected %zu samples", events.size());
@@ -335,13 +292,13 @@
         ASSERT_EQ(activate(handle, 1), Result::OK);
 
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
-        events1 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
+        events1 = getEnvironment()->collectEvents(collectionTimeoutUs, minNEvent);
 
         // second collection, without stopping the sensor
         ASSERT_EQ(batch(handle, secondCollectionPeriod, batchingPeriodInNs), Result::OK);
 
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
-        events2 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
+        events2 = getEnvironment()->collectEvents(collectionTimeoutUs, minNEvent);
 
         // end of collection, stop sensor
         ASSERT_EQ(activate(handle, 0), Result::OK);
@@ -447,16 +404,17 @@
 
         getEnvironment()->setCollection(true);
         // clean existing collections
-        collectEvents(0 /*timeLimitUs*/, 0 /*nEventLimit*/, true /*clearBeforeStart*/,
-                      false /*change collection*/);
+        getEnvironment()->collectEvents(0 /*timeLimitUs*/, 0 /*nEventLimit*/,
+                                        true /*clearBeforeStart*/, false /*change collection*/);
 
         // 0.8 + 0.2 times the batching period
         usleep(batchingPeriodInNs / 1000 * 2 / 10);
         ASSERT_EQ(flush(handle), Result::OK);
 
         // plus some time for the event to deliver
-        events = collectEvents(allowedBatchDeliverTimeNs / 1000, minFifoCount,
-                               false /*clearBeforeStart*/, false /*change collection*/);
+        events = getEnvironment()->collectEvents(allowedBatchDeliverTimeNs / 1000, minFifoCount,
+                                                 false /*clearBeforeStart*/,
+                                                 false /*change collection*/);
 
         getEnvironment()->setCollection(false);
         ASSERT_EQ(activate(handle, 0), Result::OK);
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
new file mode 100644
index 0000000..17a96ed
--- /dev/null
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
+#define ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
+
+#include <gtest/gtest.h>
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <log/log.h>
+
+template <class Event>
+class IEventCallback {
+  public:
+    virtual ~IEventCallback() = default;
+    virtual void onEvent(const Event& event) = 0;
+};
+
+template <class Event>
+class SensorsVtsEnvironmentBase {
+  public:
+    virtual void SetUp() {
+        ASSERT_TRUE(resetHal()) << "could not get hidl service";
+
+        mCollectionEnabled = false;
+        startPollingThread();
+
+        // In case framework just stopped for test and there is sensor events in the pipe,
+        // wait some time for those events to be cleared to avoid them messing up the test.
+        std::this_thread::sleep_for(std::chrono::seconds(3));
+    }
+
+    virtual void TearDown() = 0;
+
+    // Get and clear all events collected so far (like "cat" shell command).
+    // If output is nullptr, it clears all collected events.
+    void catEvents(std::vector<Event>* output) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        if (output) {
+            output->insert(output->end(), mEvents.begin(), mEvents.end());
+        }
+        mEvents.clear();
+    }
+
+    // set sensor event collection status
+    void setCollection(bool enable) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCollectionEnabled = enable;
+    }
+
+    void registerCallback(IEventCallback<Event>* callback) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCallback = callback;
+    }
+
+    void unregisterCallback() {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCallback = nullptr;
+    }
+
+    std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
+                                     bool clearBeforeStart = true, bool changeCollection = true) {
+        std::vector<Event> events;
+        constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
+
+        ALOGI("collect max of %zu events for %d us, clearBeforeStart %d", nEventLimit, timeLimitUs,
+              clearBeforeStart);
+
+        if (changeCollection) {
+            setCollection(true);
+        }
+        if (clearBeforeStart) {
+            catEvents(nullptr);
+        }
+
+        while (timeLimitUs > 0) {
+            useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
+            usleep(duration);
+            timeLimitUs -= duration;
+
+            catEvents(&events);
+            if (events.size() >= nEventLimit) {
+                break;
+            }
+            ALOGV("time to go = %d, events to go = %d", (int)timeLimitUs,
+                  (int)(nEventLimit - events.size()));
+        }
+
+        if (changeCollection) {
+            setCollection(false);
+        }
+        return events;
+    }
+
+  protected:
+    SensorsVtsEnvironmentBase(const std::string& service_name)
+        : mCollectionEnabled(false), mCallback(nullptr) {
+        mServiceName = service_name;
+    }
+    virtual ~SensorsVtsEnvironmentBase(){};
+
+    void addEvent(const Event& ev) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        if (mCollectionEnabled) {
+            mEvents.push_back(ev);
+        }
+
+        if (mCallback != nullptr) {
+            mCallback->onEvent(ev);
+        }
+    }
+
+    virtual void startPollingThread() = 0;
+    virtual bool resetHal() = 0;
+
+    std::string mServiceName;
+    bool mCollectionEnabled;
+    std::atomic_bool mStopThread;
+    std::thread mPollThread;
+    std::vector<Event> mEvents;
+    std::mutex mEventsMutex;
+
+    IEventCallback<Event>* mCallback;
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsVtsEnvironmentBase<Event>);
+};
+
+#endif  // ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
index 5d5b943..2b1b379 100644
--- a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     task_profiles ProcessCapacityHigh
+    onrestart restart media.tuner
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
index ba66595..4a642a0 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -128,7 +128,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
index 3718a93..62ee520 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
@@ -3,4 +3,5 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index bc57821..a595a93 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -180,7 +180,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 5e03731..ac38731 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -38,4 +38,5 @@
   android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode atsc3 = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
   android.hardware.tv.tuner.FrontendCableTimeInterleaveMode dvbc;
   android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode dtmb;
+  android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode isdbt;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 097fcb8..dbf631b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -40,4 +40,7 @@
   int modulationCap;
   int coderateCap;
   int guardIntervalCap;
+  int timeInterleaveCap;
+  boolean isSegmentAuto;
+  boolean isFullSegment;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
similarity index 74%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
index d7eecbb..0055793 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 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.
@@ -31,8 +31,12 @@
 // 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.radio.voice;
+package android.hardware.tv.tuner;
+/* @hide */
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable FrontendIsdbtLayerSettings {
+  android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode timeInterleave = android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+  int numOfSegment;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
index 6eadbb7..133887f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 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.
@@ -31,9 +31,12 @@
 // 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.radio;
+package android.hardware.tv.tuner;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum FrontendIsdbtPartialReceptionFlag {
+  UNDEFINED = 0,
+  AUTO = 1,
+  FALSE = 2,
+  TRUE = 4,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 6249097..605bc21 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -38,10 +38,10 @@
   long frequency;
   long endFrequency;
   android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
-  android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendIsdbtBandwidth.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtMode mode = android.hardware.tv.tuner.FrontendIsdbtMode.UNDEFINED;
-  android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendIsdbtGuardInterval.UNDEFINED;
   int serviceAreaId;
+  android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag = android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtLayerSettings[] layerSettings;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
similarity index 78%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
index 0c6c513..50adde9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 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.
@@ -31,15 +31,22 @@
 // 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.radio;
+package android.hardware.tv.tuner;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum FrontendIsdbtTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  INTERLEAVE_1_0 = 2,
+  INTERLEAVE_1_4 = 4,
+  INTERLEAVE_1_8 = 8,
+  INTERLEAVE_1_16 = 16,
+  INTERLEAVE_2_0 = 32,
+  INTERLEAVE_2_2 = 64,
+  INTERLEAVE_2_4 = 128,
+  INTERLEAVE_2_8 = 256,
+  INTERLEAVE_3_0 = 512,
+  INTERLEAVE_3_1 = 1024,
+  INTERLEAVE_3_2 = 2048,
+  INTERLEAVE_3_4 = 4096,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index 6296cfc..7677221 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -72,4 +72,6 @@
   boolean isMiso;
   boolean isLinear;
   boolean isShortFrames;
+  android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
+  android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index 7b8bc47..6342479 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -72,4 +72,6 @@
   IS_MISO = 34,
   IS_LINEAR = 35,
   IS_SHORT_FRAMES = 36,
+  ISDBT_MODE = 37,
+  ISDBT_PARTIAL_RECEPTION_FLAG = 38,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
index 8174a51..3f1ca35 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
@@ -22,6 +22,7 @@
  * Filter Delay Hint
  * Gives information to the filter to assist in delaying / accumulating filter events.
  * See FilterDelayHintType for more information regarding the hintValue units.
+ * Note: this hint is not valid for media filters.
  * @hide
  */
 @VintfStability
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 3aa17dd..106ef67 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -19,6 +19,7 @@
 import android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode;
 import android.hardware.tv.tuner.FrontendCableTimeInterleaveMode;
 import android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
 
 /**
  * @hide
@@ -31,4 +32,6 @@
     FrontendCableTimeInterleaveMode dvbc;
 
     FrontendDtmbTimeInterleaveMode dtmb;
+
+    FrontendIsdbtTimeInterleaveMode isdbt;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 4b764ad..b2bdfd4 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -46,4 +46,19 @@
      * Guard Interval Types defined by FrontendIsdbtGuardInterval.
      */
     int guardIntervalCap;
+
+    /**
+     * Time Interleaves defined by FrontendIsdbtTimeInterleaveMode.
+     */
+    int timeInterleaveCap;
+
+    /**
+     * If segment auto Supported or not.
+     */
+    boolean isSegmentAuto;
+
+    /**
+     * If full segment supported or not.
+     */
+    boolean isFullSegment;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
new file mode 100644
index 0000000..0b44ecb
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendIsdbtCoderate;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
+
+/**
+ * Layer Settings for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbtLayerSettings {
+    FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
+
+    FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
+
+    FrontendIsdbtTimeInterleaveMode timeInterleave = FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+
+    /**
+     * 0 ~ 13 and 0xFF(Auto)
+     */
+    int numOfSegment;
+}
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
similarity index 61%
rename from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
rename to tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
index 46a9b1a..81c28cd 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 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.
@@ -14,14 +14,23 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.tv.tuner;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
-
+/**
+ * Partial Reception Flag for an ISTB-T Frontend.
+ * @hide
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
+@Backing(type="int")
+enum FrontendIsdbtPartialReceptionFlag {
+    UNDEFINED = 0,
+
     /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
+     * Hardware is able to detect and set Partial Reception Flag automatically.
      */
-    CdmaInformationRecord[] infoRec;
+    AUTO = 1 << 0,
+
+    FALSE = 1 << 1,
+
+    TRUE = 1 << 2,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 08f6130..23a4769 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -17,10 +17,10 @@
 package android.hardware.tv.tuner;
 
 import android.hardware.tv.tuner.FrontendIsdbtBandwidth;
-import android.hardware.tv.tuner.FrontendIsdbtCoderate;
 import android.hardware.tv.tuner.FrontendIsdbtGuardInterval;
+import android.hardware.tv.tuner.FrontendIsdbtLayerSettings;
 import android.hardware.tv.tuner.FrontendIsdbtMode;
-import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
 import android.hardware.tv.tuner.FrontendSpectralInversion;
 
 /**
@@ -41,15 +41,15 @@
 
     FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
 
-    FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
-
     FrontendIsdbtBandwidth bandwidth = FrontendIsdbtBandwidth.UNDEFINED;
 
     FrontendIsdbtMode mode = FrontendIsdbtMode.UNDEFINED;
 
-    FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
-
     FrontendIsdbtGuardInterval guardInterval = FrontendIsdbtGuardInterval.UNDEFINED;
 
     int serviceAreaId;
+
+    FrontendIsdbtPartialReceptionFlag partialReceptionFlag = FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+
+    FrontendIsdbtLayerSettings[] layerSettings;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
new file mode 100644
index 0000000..6192fca
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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.tv.tuner;
+
+/**
+ * Time Interleave Mode for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtTimeInterleaveMode {
+    UNDEFINED = 0,
+
+    /**
+     * Hardware is able to detect and set Time Interleave Mode automatically.
+     */
+    AUTO = 1 << 0,
+
+    INTERLEAVE_1_0 = 1 << 1,
+
+    INTERLEAVE_1_4 = 1 << 2,
+
+    INTERLEAVE_1_8 = 1 << 3,
+
+    INTERLEAVE_1_16 = 1 << 4,
+
+    INTERLEAVE_2_0 = 1 << 5,
+
+    INTERLEAVE_2_2 = 1 << 6,
+
+    INTERLEAVE_2_4 = 1 << 7,
+
+    INTERLEAVE_2_8 = 1 << 8,
+
+    INTERLEAVE_3_0 = 1 << 9,
+
+    INTERLEAVE_3_1 = 1 << 10,
+
+    INTERLEAVE_3_2 = 1 << 11,
+
+    INTERLEAVE_3_4 = 1 << 12,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index ddbd0f8..9302b76 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -21,6 +21,8 @@
 import android.hardware.tv.tuner.FrontendGuardInterval;
 import android.hardware.tv.tuner.FrontendInnerFec;
 import android.hardware.tv.tuner.FrontendInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtMode;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
 import android.hardware.tv.tuner.FrontendModulation;
 import android.hardware.tv.tuner.FrontendModulationStatus;
 import android.hardware.tv.tuner.FrontendRollOff;
@@ -190,4 +192,14 @@
      * If short frames is enabled or not.
      */
     boolean isShortFrames;
+
+    /**
+     * ISDB-T Mode.
+     */
+    FrontendIsdbtMode isdbtMode;
+
+    /**
+     * ISDB-T Partial Reception Flag.
+     */
+    FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 93b75b0..103a4ab 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -208,4 +208,14 @@
      * If short frames is enabled or not.
      */
     IS_SHORT_FRAMES,
+
+    /**
+     * ISDB-T Mode.
+     */
+    ISDBT_MODE,
+
+    /**
+     * ISDB-T Partial Reception Flag.
+     */
+    ISDBT_PARTIAL_RECEPTION_FLAG,
 }
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index c377772..5f61c8d 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -34,16 +34,141 @@
 
 #define WAIT_TIMEOUT 3000000000
 
-Filter::Filter() {}
+FilterCallbackScheduler::FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb)
+    : mCallback(cb), mDataLength(0), mTimeDelayInMs(0), mDataSizeDelayInBytes(0) {
+    start();
+}
+
+FilterCallbackScheduler::~FilterCallbackScheduler() {
+    stop();
+}
+
+void FilterCallbackScheduler::onFilterEvent(DemuxFilterEvent&& event) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mCallbackBuffer.push_back(std::move(event));
+    mDataLength += getDemuxFilterEventDataLength(event);
+
+    if (mDataLength >= mDataSizeDelayInBytes) {
+        // size limit has been reached, send out events
+        mCv.notify_all();
+    }
+}
+
+void FilterCallbackScheduler::onFilterStatus(const DemuxFilterStatus& status) {
+    if (mCallback) {
+        mCallback->onFilterStatus(status);
+    }
+}
+
+void FilterCallbackScheduler::flushEvents() {
+    std::unique_lock<std::mutex> lock(mLock);
+    mCallbackBuffer.clear();
+    mDataLength = 0;
+}
+
+void FilterCallbackScheduler::setTimeDelayHint(int timeDelay) {
+    // updating the setTimeDelay does not go into effect until the condition
+    // variable times out or is notified.
+    // One possibility is to notify the condition variable right away when the
+    // time delay changes, but I don't see the benefit over waiting for the next
+    // timeout / push, since -- in any case -- this will not change very often.
+    mTimeDelayInMs = timeDelay;
+}
+
+void FilterCallbackScheduler::setDataSizeDelayHint(int dataSizeDelay) {
+    // similar to updating the time delay hint, when mDataSizeDelayInBytes
+    // changes, this will not go into immediate effect, but will wait until the
+    // next filterEvent.
+    // We could technically check the current data length and notify the
+    // condition variable if we wanted to, but again, this may be overkill.
+    mDataSizeDelayInBytes = dataSizeDelay;
+}
+
+bool FilterCallbackScheduler::hasCallbackRegistered() const {
+    return mCallback != nullptr;
+}
+
+void FilterCallbackScheduler::start() {
+    mIsRunning = true;
+    mCallbackThread = std::thread(&FilterCallbackScheduler::threadLoop, this);
+}
+
+void FilterCallbackScheduler::stop() {
+    mIsRunning = false;
+    if (mCallbackThread.joinable()) {
+        mCv.notify_all();
+        mCallbackThread.join();
+    }
+}
+
+void FilterCallbackScheduler::threadLoop() {
+    while (mIsRunning) {
+        threadLoopOnce();
+    }
+}
+
+void FilterCallbackScheduler::threadLoopOnce() {
+    std::unique_lock<std::mutex> lock(mLock);
+    // mTimeDelayInMs is an atomic value, so it should be copied into a local
+    // variable before use (to make sure both the if statement and wait_for use
+    // the same value).
+    int timeDelayInMs = mTimeDelayInMs;
+    if (timeDelayInMs > 0) {
+        mCv.wait_for(lock, std::chrono::milliseconds(timeDelayInMs));
+    } else {
+        // no reason to timeout, just wait until main thread determines it's
+        // okay to send data.
+        mCv.wait(lock);
+    }
+
+    // condition_variable wait locks mutex on timeout / notify
+    // Note: if stop() has been called in the meantime, do not send more filter
+    // events.
+    if (mIsRunning && !mCallbackBuffer.empty()) {
+        if (mCallback) {
+            mCallback->onFilterEvent(mCallbackBuffer);
+        }
+        mCallbackBuffer.clear();
+        mDataLength = 0;
+    }
+    lock.unlock();
+}
+
+int FilterCallbackScheduler::getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
+    // there is a risk that dataLength could be a negative value, but it
+    // *should* be safe to assume that it is always positive.
+    switch (event.getTag()) {
+        case DemuxFilterEvent::Tag::section:
+            return event.get<DemuxFilterEvent::Tag::section>().dataLength;
+        case DemuxFilterEvent::Tag::media:
+            return event.get<DemuxFilterEvent::Tag::media>().dataLength;
+        case DemuxFilterEvent::Tag::pes:
+            return event.get<DemuxFilterEvent::Tag::pes>().dataLength;
+        case DemuxFilterEvent::Tag::download:
+            return event.get<DemuxFilterEvent::Tag::download>().dataLength;
+        case DemuxFilterEvent::Tag::ipPayload:
+            return event.get<DemuxFilterEvent::Tag::ipPayload>().dataLength;
+
+        case DemuxFilterEvent::Tag::tsRecord:
+        case DemuxFilterEvent::Tag::mmtpRecord:
+        case DemuxFilterEvent::Tag::temi:
+        case DemuxFilterEvent::Tag::monitorEvent:
+        case DemuxFilterEvent::Tag::startId:
+            // these events do not include a payload and should therefore return
+            // 0.
+            // do not add a default option, so this will not compile when new types
+            // are added.
+            return 0;
+    }
+}
 
 Filter::Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
-               const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux) {
-    mType = type;
-    mFilterId = filterId;
-    mBufferSize = bufferSize;
-    mDemux = demux;
-    mCallback = cb;
-
+               const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux)
+    : mDemux(demux),
+      mCallbackScheduler(cb),
+      mFilterId(filterId),
+      mBufferSize(bufferSize),
+      mType(type) {
     switch (mType.mainType) {
         case DemuxFilterMainType::TS:
             if (mType.subType.get<DemuxFilterSubType::Tag::tsFilterType>() ==
@@ -112,9 +237,29 @@
 }
 
 ::ndk::ScopedAStatus Filter::setDelayHint(const FilterDelayHint& in_hint) {
+    if (mIsMediaFilter) {
+        // delay hint is not supported for media filters
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
     ALOGV("%s", __FUNCTION__);
-    (void)in_hint;
-    // TODO: implement
+    if (in_hint.hintValue < 0) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    }
+
+    switch (in_hint.hintType) {
+        case FilterDelayHintType::TIME_DELAY_IN_MS:
+            mCallbackScheduler.setTimeDelayHint(in_hint.hintValue);
+            break;
+        case FilterDelayHintType::DATA_SIZE_DELAY_IN_BYTES:
+            mCallbackScheduler.setDataSizeDelayHint(in_hint.hintValue);
+            break;
+        default:
+            return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                    static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    }
 
     return ::ndk::ScopedAStatus::ok();
 }
@@ -155,40 +300,36 @@
 ::ndk::ScopedAStatus Filter::start() {
     ALOGV("%s", __FUNCTION__);
     mFilterThreadRunning = true;
-    vector<DemuxFilterEvent> events;
+    std::vector<DemuxFilterEvent> events;
     // All the filter event callbacks in start are for testing purpose.
     switch (mType.mainType) {
         case DemuxFilterMainType::TS:
             createMediaEvent(events);
-            mCallback->onFilterEvent(events);
             createTsRecordEvent(events);
-            mCallback->onFilterEvent(events);
             createTemiEvent(events);
-            mCallback->onFilterEvent(events);
             break;
         case DemuxFilterMainType::MMTP:
             createDownloadEvent(events);
-            mCallback->onFilterEvent(events);
             createMmtpRecordEvent(events);
-            mCallback->onFilterEvent(events);
             break;
         case DemuxFilterMainType::IP:
             createSectionEvent(events);
-            mCallback->onFilterEvent(events);
             createIpPayloadEvent(events);
-            mCallback->onFilterEvent(events);
             break;
         case DemuxFilterMainType::TLV:
             createMonitorEvent(events);
-            mCallback->onFilterEvent(events);
             break;
         case DemuxFilterMainType::ALP:
             createMonitorEvent(events);
-            mCallback->onFilterEvent(events);
             break;
         default:
             break;
     }
+
+    for (auto&& event : events) {
+        mCallbackScheduler.onFilterEvent(std::move(event));
+    }
+
     return startFilterLoop();
 }
 
@@ -200,6 +341,8 @@
         mFilterThread.join();
     }
 
+    mCallbackScheduler.flushEvents();
+
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -327,15 +470,14 @@
     if (newScramblingStatus ^ mScramblingStatusMonitored) {
         mScramblingStatusMonitored = newScramblingStatus;
         if (mScramblingStatusMonitored) {
-            if (mCallback != nullptr) {
+            if (mCallbackScheduler.hasCallbackRegistered()) {
                 // Assuming current status is always NOT_SCRAMBLED
-                vector<DemuxFilterEvent> events;
-                DemuxFilterMonitorEvent monitorEvent;
-                events.resize(1);
-                monitorEvent.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(
+                auto monitorEvent = DemuxFilterMonitorEvent::make<
+                        DemuxFilterMonitorEvent::Tag::scramblingStatus>(
                         ScramblingStatus::NOT_SCRAMBLED);
-                events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
-                mCallback->onFilterEvent(events);
+                auto event =
+                        DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(monitorEvent);
+                mCallbackScheduler.onFilterEvent(std::move(event));
             } else {
                 return ::ndk::ScopedAStatus::fromServiceSpecificError(
                         static_cast<int32_t>(Result::INVALID_STATE));
@@ -347,14 +489,13 @@
     if (newIpCid ^ mIpCidMonitored) {
         mIpCidMonitored = newIpCid;
         if (mIpCidMonitored) {
-            if (mCallback != nullptr) {
+            if (mCallbackScheduler.hasCallbackRegistered()) {
                 // Return random cid
-                vector<DemuxFilterEvent> events;
-                DemuxFilterMonitorEvent monitorEvent;
-                events.resize(1);
-                monitorEvent.set<DemuxFilterMonitorEvent::Tag::cid>(1);
-                events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
-                mCallback->onFilterEvent(events);
+                auto monitorEvent =
+                        DemuxFilterMonitorEvent::make<DemuxFilterMonitorEvent::Tag::cid>(1);
+                auto event =
+                        DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(monitorEvent);
+                mCallbackScheduler.onFilterEvent(std::move(event));
             } else {
                 return ::ndk::ScopedAStatus::fromServiceSpecificError(
                         static_cast<int32_t>(Result::INVALID_STATE));
@@ -410,26 +551,26 @@
         }
 
         // After successfully write, send a callback and wait for the read to be done
-        if (mCallback != nullptr) {
+        if (mCallbackScheduler.hasCallbackRegistered()) {
             if (mConfigured) {
-                vector<DemuxFilterEvent> startEvent;
-                startEvent.resize(1);
-                startEvent[0].set<DemuxFilterEvent::Tag::startId>(mStartId++);
-                mCallback->onFilterEvent(startEvent);
+                auto startEvent =
+                        DemuxFilterEvent::make<DemuxFilterEvent::Tag::startId>(mStartId++);
+                mCallbackScheduler.onFilterEvent(std::move(startEvent));
                 mConfigured = false;
             }
-            mCallback->onFilterEvent(mFilterEvents);
+
+            for (auto&& event : mFilterEvents) {
+                mCallbackScheduler.onFilterEvent(std::move(event));
+            }
         } else {
             ALOGD("[Filter] filter callback is not configured yet.");
             mFilterThreadRunning = false;
             return;
         }
 
-        mFilterEvents.resize(0);
+        mFilterEvents.clear();
         mFilterStatus = DemuxFilterStatus::DATA_READY;
-        if (mCallback != nullptr) {
-            mCallback->onFilterStatus(mFilterStatus);
-        }
+        mCallbackScheduler.onFilterStatus(mFilterStatus);
         break;
     }
 
@@ -460,10 +601,10 @@
                     continue;
                 }
                 // After successfully write, send a callback and wait for the read to be done
-                if (mCallback != nullptr) {
-                    mCallback->onFilterEvent(mFilterEvents);
+                for (auto&& event : mFilterEvents) {
+                    mCallbackScheduler.onFilterEvent(std::move(event));
                 }
-                mFilterEvents.resize(0);
+                mFilterEvents.clear();
                 break;
             }
             // We do not wait for the last read to be done
@@ -499,9 +640,7 @@
     DemuxFilterStatus newStatus = checkFilterStatusChange(
             availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
     if (mFilterStatus != newStatus) {
-        if (mCallback != nullptr) {
-            mCallback->onFilterStatus(newStatus);
-        }
+        mCallbackScheduler.onFilterStatus(newStatus);
         mFilterStatus = newStatus;
     }
 }
@@ -657,9 +796,7 @@
             ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
         }
 
-        int size = mFilterEvents.size();
-        mFilterEvents.resize(size + 1);
-        mFilterEvents[size].set<DemuxFilterEvent::Tag::pes>(pesEvent);
+        mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
         mPesOutput.clear();
     }
 
@@ -763,11 +900,7 @@
             .firstMbInSlice = 0,  // random address
     };
 
-    int size;
-    size = mFilterEvents.size();
-    mFilterEvents.resize(size + 1);
-    mFilterEvents[size].set<DemuxFilterEvent::Tag::tsRecord>(recordEvent);
-
+    mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
     mRecordFilterOutput.clear();
     return ::ndk::ScopedAStatus::ok();
 }
@@ -789,8 +922,6 @@
     if (!writeDataToFilterMQ(data)) {
         return false;
     }
-    int size = mFilterEvents.size();
-    mFilterEvents.resize(size + 1);
     DemuxFilterSectionEvent secEvent;
     secEvent = {
             // temp dump meta data
@@ -799,7 +930,7 @@
             .sectionNum = 1,
             .dataLength = static_cast<int32_t>(data.size()),
     };
-    mFilterEvents[size].set<DemuxFilterEvent::Tag::section>(secEvent);
+    mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
     return true;
 }
 
@@ -888,19 +1019,16 @@
     mDataId2Avfd[dataId] = dup(av_fd);
 
     // Create mediaEvent and send callback
-    int size = mFilterEvents.size();
-    mFilterEvents.resize(size + 1);
-
-    mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
-            ::android::dupToAidl(nativeHandle);
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
-            static_cast<int64_t>(output.size());
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
+    auto event = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+    auto& mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
+    mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+    mediaEvent.dataLength = static_cast<int64_t>(output.size());
+    mediaEvent.avDataId = static_cast<int64_t>(dataId);
     if (mPts) {
-        mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+        mediaEvent.pts = mPts;
         mPts = 0;
     }
+    mFilterEvents.push_back(std::move(event));
 
     // Clear and log
     native_handle_close(nativeHandle);
@@ -931,18 +1059,17 @@
     }
 
     // Create mediaEvent and send callback
-    int size = mFilterEvents.size();
-    mFilterEvents.resize(size + 1);
-    mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
-            ::android::dupToAidl(nativeHandle);
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().offset = mSharedAvMemOffset;
-    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
-            static_cast<int64_t>(output.size());
+    auto event = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+    auto& mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
+    mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+    mediaEvent.offset = mSharedAvMemOffset;
+    mediaEvent.dataLength = static_cast<int64_t>(output.size());
     if (mPts) {
-        mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+        mediaEvent.pts = mPts;
         mPts = 0;
     }
+    mFilterEvents.push_back(std::move(event));
+
     mSharedAvMemOffset += output.size();
 
     // Clear and log
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index 11bbc11..7298561 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -18,6 +18,8 @@
 
 #include <aidl/android/hardware/tv/tuner/BnFilter.h>
 #include <aidl/android/hardware/tv/tuner/Constant.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterEvent.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterStatus.h>
 
 #include <fmq/AidlMessageQueue.h>
 #include <inttypes.h>
@@ -25,6 +27,7 @@
 #include <math.h>
 #include <sys/stat.h>
 #include <atomic>
+#include <condition_variable>
 #include <set>
 #include <thread>
 
@@ -52,10 +55,51 @@
 class Demux;
 class Dvr;
 
-class Filter : public BnFilter {
+class FilterCallbackScheduler final {
   public:
-    Filter();
+    FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb);
+    ~FilterCallbackScheduler();
 
+    void onFilterEvent(DemuxFilterEvent&& event);
+    void onFilterStatus(const DemuxFilterStatus& status);
+
+    void setTimeDelayHint(int timeDelay);
+    void setDataSizeDelayHint(int dataSizeDelay);
+
+    bool hasCallbackRegistered() const;
+
+    void flushEvents();
+
+  private:
+    void start();
+    void stop();
+
+    void threadLoop();
+    void threadLoopOnce();
+
+    static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event);
+
+  private:
+    std::shared_ptr<IFilterCallback> mCallback;
+    std::thread mCallbackThread;
+    std::atomic<bool> mIsRunning;
+
+    // mLock protects mCallbackBuffer, mCv, and mDataLength
+    std::mutex mLock;
+    std::vector<DemuxFilterEvent> mCallbackBuffer;
+    std::condition_variable mCv;
+    int mDataLength;
+
+    // both of these need to be atomic (not just mTimeDelayInMs) as this class
+    // needs to be threadsafe.
+    std::atomic<int> mTimeDelayInMs;
+    std::atomic<int> mDataSizeDelayInBytes;
+};
+
+class Filter : public BnFilter {
+    friend class FilterCallbackScheduler;
+
+  public:
     Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
            const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux);
 
@@ -104,10 +148,8 @@
     std::shared_ptr<Demux> mDemux;
     // Dvr reference once the filter is attached to any
     std::shared_ptr<Dvr> mDvr = nullptr;
-    /**
-     * Filter callbacks used on filter events or FMQ status
-     */
-    std::shared_ptr<IFilterCallback> mCallback = nullptr;
+
+    FilterCallbackScheduler mCallbackScheduler;
 
     int64_t mFilterId;
     int32_t mCid = static_cast<int32_t>(Constant::INVALID_IP_FILTER_CONTEXT_ID);
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index f9e697e..77d20e2 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -607,6 +607,13 @@
                         status.set<FrontendStatus::interleaving>(interleaves);
                         break;
                     }
+                    case FrontendType::ISDBT: {
+                        interleave.set<FrontendInterleaveMode::Tag::isdbt>(
+                                FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0); // value = 1 << 1
+                        interleaves.push_back(interleave);
+                        status.set<FrontendStatus::interleaving>(interleaves);
+                        break;
+                    }
                     default:
                         break;
                 }
@@ -660,6 +667,15 @@
                 status.set<FrontendStatus::isShortFrames>(true);
                 break;
             }
+            case FrontendStatusType::ISDBT_MODE: {
+                status.set<FrontendStatus::isdbtMode>(FrontendIsdbtMode::AUTO);
+                break;
+            }
+            case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+                status.set<FrontendStatus::partialReceptionFlag>(
+                        FrontendIsdbtPartialReceptionFlag::AUTO);
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index 8468929..badb08f 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -119,6 +119,10 @@
             .coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
                            (int)FrontendIsdbtCoderate::CODERATE_6_7,
             .guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
+            .timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
+                                 (int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
+            .isSegmentAuto = true,
+            .isFullSegment = true,
     };
     capsIsdbt.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
     mFrontendCaps[5] = capsIsdbt;
@@ -131,6 +135,9 @@
             FrontendStatusType::GUARD_INTERVAL,
             FrontendStatusType::TRANSMISSION_MODE,
             FrontendStatusType::ISDBT_SEGMENTS,
+            FrontendStatusType::ISDBT_MODE,
+            FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
+            FrontendStatusType::INTERLEAVINGS,
     };
     mFrontendStatusCaps[5] = statusCaps;
 
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
index fa09456..d0248c2 100644
--- a/tv/tuner/aidl/default/tuner-default.rc
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index 91a0a4a..c965d95 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -74,7 +74,6 @@
 
     void setFilterId(int32_t filterId) { mFilterId = filterId; }
     void setFilterInterface(std::shared_ptr<IFilter> filter) { mFilter = filter; }
-    void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
     void setSharedHandle(native_handle_t* sharedHandle) { mAvSharedHandle = sharedHandle; }
     void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
 
@@ -89,7 +88,6 @@
   private:
     int32_t mFilterId;
     std::shared_ptr<IFilter> mFilter;
-    FilterEventType mFilterEventType;
 
     native_handle_t* mAvSharedHandle = nullptr;
     uint64_t mAvSharedMemSize = -1;
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 77add8e..6204803 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -171,7 +171,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
@@ -387,6 +388,16 @@
                             expectStatuses[i].get<FrontendStatus::Tag::isShortFrames>());
                 break;
             }
+            case FrontendStatusType::ISDBT_MODE: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isdbtMode>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::isdbtMode>());
+                break;
+            }
+            case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/uwb/aidl/vts/OWNERS b/uwb/OWNERS
similarity index 100%
rename from uwb/aidl/vts/OWNERS
rename to uwb/OWNERS
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 0d1ebc2..99fd094 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -35,6 +35,7 @@
                 "//apex_available:platform",
                 "com.android.uwb",
             ],
+            min_sdk_version: "current",
         },
     },
 }
@@ -53,9 +54,6 @@
             ],
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
                 "com.android.uwb",
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 6eadbb7..774133e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -2,10 +2,10 @@
  * Copyright (C) 2021 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 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
+ *        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,
@@ -31,9 +31,8 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbAndroidCapabilities {
+  POWER_STATS_QUERY = 1,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index 6eadbb7..4e3d4a2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -2,10 +2,10 @@
  * Copyright (C) 2021 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 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
+ *        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,
@@ -31,9 +31,8 @@
 // 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.radio;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGidAndroidOids {
+  ANDROID_GET_POWER_STATS = 0,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
index 6eadbb7..30a0a1b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -2,10 +2,10 @@
  * Copyright (C) 2021 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 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
+ *        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,
@@ -31,9 +31,8 @@
 // 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.radio;
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum UwbVendorSessionInitSessionType {
+  CCC = 160,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
index 7074753..c4cb47b 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
@@ -40,6 +40,7 @@
   void open(in android.hardware.uwb.IUwbClientCallback clientCallback);
   void close();
   void coreInit();
-  int getSupportedVendorUciVersion();
+  int getSupportedAndroidUciVersion();
+  long getSupportedAndroidCapabilities();
   int sendUciMessage(in byte[] data);
 }
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
old mode 100755
new mode 100644
index 9530af4..0c98611
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -49,14 +49,24 @@
      */
     void coreInit();
 
-     /**
-      * Supported version of vendor UCI specification.
-      *
-      * This corresponds to the version of the "android.hardware.uwb.fira_android" types-only
-      * package included in the HAL implementation. This vendor params/commands package will be
-      * updated on a different cadence to the main UWB HAL interface package.
-      */
-    int getSupportedVendorUciVersion();
+    /**
+     * Supported version of vendor UCI specification.
+     *
+     * @return Returns the version of the "android.hardware.uwb.fira_android" types-only
+     * package included in the HAL implementation. This vendor params/commands package will be
+     * updated on a different cadence to the main UWB HAL interface package.
+     */
+    int getSupportedAndroidUciVersion();
+
+    /**
+     * Mechanism to allow HAL implementation to optionally expose features that are defined
+     * in the "android.hardware.uwb.fira_android" types-only package.
+     *
+     * @return Returns the bitmask of capabilities
+     * (android.hardware.uwb.fira_android.UwbAndroidCapabilities) that is supported by the
+     * HAL implementation.
+     */
+    long getSupportedAndroidCapabilities();
 
     /**
      * Write the UCI message to the UWB Subsystem.
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
new file mode 100644
index 0000000..3486d5a
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.uwb.fira_android;
+
+/**
+ * Android specific capabilities should be defined here.
+ *
+ * For any features enabled via the FIRA vendor commands for Android, use this bitmask
+ * to allow devices to expose the features supported by the HAL implementation.
+ *
+ */
+@VintfStability
+@Backing(type="long")
+enum UwbAndroidCapabilities {
+    /** TODO: Change the name if necessary when the corresponding vendor commands are added */
+    POWER_STATS_QUERY = 0x1,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
new file mode 100644
index 0000000..de4a2d8
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.uwb.fira_android;
+
+/**
+ * Android specific vendor command OIDs should be defined here.
+ *
+ */
+@VintfStability
+@Backing(type="byte")
+enum UwbVendorGidAndroidOids {
+    // Used by the command and response to get UWB power related stats.
+    // Supported only if the value returned by getSupportedAndroidCapabilities()
+    // has the bit of UwbAndroidCapabilities.POWER_STATS_QUERY set to 1.
+    ANDROID_GET_POWER_STATS = 0x0,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
new file mode 100644
index 0000000..1e2c817
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.uwb.fira_android;
+
+/**
+ * Android specific session type set in UCI command:
+ * GID: 0001b (UWB Session config Group)
+ * OID: 000000b (SESSION_INIT_CMD)
+ *
+ * Note: Refer to Table 13 of the UCI specification for the other
+ * session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum UwbVendorSessionInitSessionType {
+    /** Added in vendor version 0. */
+    CCC = 0xA0,
+}
diff --git a/uwb/aidl/default/OWNERS b/uwb/aidl/default/OWNERS
deleted file mode 100644
index c4ad416..0000000
--- a/uwb/aidl/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 1042770
-include platform/packages/modules/Uwb:/OWNERS
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
index fe64fa7..10dbdb6 100644
--- a/uwb/aidl/default/uwb_chip.cpp
+++ b/uwb/aidl/default/uwb_chip.cpp
@@ -17,7 +17,8 @@
 #include "uwb.h"
 
 namespace {
-constexpr static int kVendorUciVersion = 1;
+constexpr static int32_t kAndroidUciVersion = 1;
+constexpr static int64_t kAndroidCapabilities = 0;
 }
 
 namespace android {
@@ -50,8 +51,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus UwbChip::getSupportedVendorUciVersion(int32_t* version) {
-    *version = kVendorUciVersion;
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
+    *version = kAndroidUciVersion;
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidCapabilities(int64_t* capabilities) {
+    *capabilities = kAndroidCapabilities;
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
index ef1d5b6..ca97120 100644
--- a/uwb/aidl/default/uwb_chip.h
+++ b/uwb/aidl/default/uwb_chip.h
@@ -37,7 +37,8 @@
     ::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
     ::ndk::ScopedAStatus close() override;
     ::ndk::ScopedAStatus coreInit() override;
-    ::ndk::ScopedAStatus getSupportedVendorUciVersion(int32_t* version) override;
+    ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
+    ::ndk::ScopedAStatus getSupportedAndroidCapabilities(int64_t* capabilities) override;
     ::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
                                         int32_t* bytes_written) override;
 
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 9ac2678..3820c0f 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -166,15 +166,23 @@
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
 }
 
-TEST_P(UwbAidl, ChipGetSupportedVendorUciVersion) {
+TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
     const auto iuwb_chip = getAnyChipAndOpen();
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
 
-    int version;
-    EXPECT_TRUE(iuwb_chip->getSupportedVendorUciVersion(&version).isOk());
+    int32_t version;
+    EXPECT_TRUE(iuwb_chip->getSupportedAndroidUciVersion(&version).isOk());
     EXPECT_GT(version, 0);
 }
 
+TEST_P(UwbAidl, ChipGetSupportedAndroidCapabilities) {
+    const auto iuwb_chip = getAnyChipAndOpen();
+    EXPECT_TRUE(iuwb_chip->coreInit().isOk());
+
+    int64_t capabilities;
+    EXPECT_TRUE(iuwb_chip->getSupportedAndroidCapabilities(&capabilities).isOk());
+}
+
 TEST_P(UwbAidl, ChipGetName) {
     std::string chip_name = getAnyChipName();
     std::shared_ptr<IUwbChip> iuwb_chip;
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 53f8c0e..09cc21b 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -417,6 +417,9 @@
 
             if (isPrimitiveSupported) {
                 EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+                if (primitive != CompositePrimitive::NOOP) {
+                    ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
+                }
             } else {
                 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
             }
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index d37da08..e58cf5e 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -16,9 +16,10 @@
     srcs: ["VtsHalHostapdTargetTest.cpp"],
     shared_libs: [
         "libbinder",
+        "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.wifi.hostapd-V1-cpp",
+        "android.hardware.wifi.hostapd-V1-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 92fbf50..41c54b3 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -14,33 +14,33 @@
  * limitations under the License.
  */
 #include <VtsCoreUtil.h>
-
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
-#include <android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapdCallback.h>
+#include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
+using aidl::android::hardware::wifi::hostapd::BandMask;
+using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
+using aidl::android::hardware::wifi::hostapd::ChannelParams;
+using aidl::android::hardware::wifi::hostapd::DebugLevel;
+using aidl::android::hardware::wifi::hostapd::EncryptionType;
+using aidl::android::hardware::wifi::hostapd::FrequencyRange;
+using aidl::android::hardware::wifi::hostapd::Ieee80211ReasonCode;
+using aidl::android::hardware::wifi::hostapd::IfaceParams;
+using aidl::android::hardware::wifi::hostapd::IHostapd;
+using aidl::android::hardware::wifi::hostapd::NetworkParams;
 using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::hardware::wifi::hostapd::BandMask;
-using android::hardware::wifi::hostapd::ChannelParams;
-using android::hardware::wifi::hostapd::DebugLevel;
-using android::hardware::wifi::hostapd::EncryptionType;
-using android::hardware::wifi::hostapd::FrequencyRange;
-using android::hardware::wifi::hostapd::Ieee80211ReasonCode;
-using android::hardware::wifi::hostapd::IfaceParams;
-using android::hardware::wifi::hostapd::IHostapd;
-using android::hardware::wifi::hostapd::NetworkParams;
 
 namespace {
 const unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', '2', '3', '4', '5'};
-const String16 kIfaceName = String16("wlan0");
-const String16 kPassphrase = String16("test12345");
-const String16 kInvalidMinPassphrase = String16("test");
-const String16 kInvalidMaxPassphrase = String16(
-    "0123456789012345678901234567890123456789012345678901234567890123456789");
+const std::string kIfaceName = "wlan0";
+const std::string kPassphrase = "test12345";
+const std::string kInvalidMinPassphrase = "test";
+const std::string kInvalidMaxPassphrase =
+    "0123456789012345678901234567890123456789012345678901234567890123456789";
 const int kIfaceChannel = 6;
 const int kIfaceInvalidChannel = 567;
 const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
@@ -56,8 +56,8 @@
 class HostapdAidl : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        hostapd = android::waitForDeclaredService<IHostapd>(
-            String16(GetParam().c_str()));
+        hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService(GetParam().c_str())));
         ASSERT_NE(hostapd, nullptr);
         EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
         isAcsSupport = testing::checkSubstringInCommandOutput(
@@ -77,12 +77,12 @@
         sleep(3);
     }
 
-    sp<IHostapd> hostapd;
+    std::shared_ptr<IHostapd> hostapd;
     bool isAcsSupport;
     bool isWpa3SaeSupport;
     bool isBridgedSupport;
 
-    IfaceParams getIfaceParamsWithoutAcs(String16 iface_name) {
+    IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
         IfaceParams iface_params;
         ChannelParams channelParams;
         std::vector<ChannelParams> vec_channelParams;
@@ -103,7 +103,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithBridgedModeACS(String16 iface_name) {
+    IfaceParams getIfaceParamsWithBridgedModeACS(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].enableAcs = true;
         iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -121,7 +121,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcs(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].enableAcs = true;
         iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -131,7 +131,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcsAndFreqRange(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcsAndFreqRange(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithAcs(iface_name);
         FrequencyRange freqRange;
         freqRange.startMhz = 2412;
@@ -143,7 +143,8 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
+        std::string iface_name) {
         IfaceParams iface_params =
             getIfaceParamsWithAcsAndFreqRange(iface_name);
         iface_params.channelParams[0].acsChannelFreqRangesMhz[0].startMhz =
@@ -153,7 +154,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithInvalidChannel(String16 iface_name) {
+    IfaceParams getIfaceParamsWithInvalidChannel(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].channel = kIfaceInvalidChannel;
         return iface_params;
@@ -215,11 +216,37 @@
     NetworkParams getInvalidSaeNwParams() {
         NetworkParams nw_params = getOpenNwParams();
         nw_params.encryptionType = EncryptionType::WPA3_SAE;
-        nw_params.passphrase = String16("");
+        nw_params.passphrase = "";
         return nw_params;
     }
 };
 
+class HostapdCallback : public BnHostapdCallback {
+   public:
+    HostapdCallback() = default;
+    ::ndk::ScopedAStatus onApInstanceInfoChanged(
+        const ::aidl::android::hardware::wifi::hostapd::ApInfo &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onConnectedClientsChanged(
+        const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onFailure(const std::string &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+/**
+ * Register callback
+ */
+TEST_P(HostapdAidl, RegisterCallback) {
+    std::shared_ptr<HostapdCallback> callback =
+        ndk::SharedRefBase::make<HostapdCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(hostapd->registerCallback(callback).isOk());
+}
+
 /**
  * Adds an access point with PSK network config & ACS enabled.
  * Access point creation should pass.